Whamcloud - gitweb
LU-6142 tests: Fix style issues for mmap_sanity.c
[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         test_mkdir $DIR/$tdir
2462         pool_add $POOL || error "pool_add failed"
2463         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2464
2465         local skip27D
2466         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2467                 skip27D+="-s 29"
2468         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2469                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2470                         skip27D+=" -s 30,31"
2471         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code $SEL_VER) ] &&
2472                 skip27D+="-s 32"
2473         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2474           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2475                 skip27D+=" -s 32,33"
2476         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2477                 error "llapi_layout_test failed"
2478
2479         destroy_test_pools || error "destroy test pools failed"
2480 }
2481 run_test 27D "validate llapi_layout API"
2482
2483 # Verify that default_easize is increased from its initial value after
2484 # accessing a widely striped file.
2485 test_27E() {
2486         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2487         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2488                 skip "client does not have LU-3338 fix"
2489
2490         # 72 bytes is the minimum space required to store striping
2491         # information for a file striped across one OST:
2492         # (sizeof(struct lov_user_md_v3) +
2493         #  sizeof(struct lov_user_ost_data_v1))
2494         local min_easize=72
2495         $LCTL set_param -n llite.*.default_easize $min_easize ||
2496                 error "lctl set_param failed"
2497         local easize=$($LCTL get_param -n llite.*.default_easize)
2498
2499         [ $easize -eq $min_easize ] ||
2500                 error "failed to set default_easize"
2501
2502         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2503                 error "setstripe failed"
2504         # In order to ensure stat() call actually talks to MDS we need to
2505         # do something drastic to this file to shake off all lock, e.g.
2506         # rename it (kills lookup lock forcing cache cleaning)
2507         mv $DIR/$tfile $DIR/${tfile}-1
2508         ls -l $DIR/${tfile}-1
2509         rm $DIR/${tfile}-1
2510
2511         easize=$($LCTL get_param -n llite.*.default_easize)
2512
2513         [ $easize -gt $min_easize ] ||
2514                 error "default_easize not updated"
2515 }
2516 run_test 27E "check that default extended attribute size properly increases"
2517
2518 test_27F() { # LU-5346/LU-7975
2519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2520         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2521         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2522                 skip "Need MDS version at least 2.8.51"
2523         remote_ost_nodsh && skip "remote OST with nodsh"
2524
2525         test_mkdir $DIR/$tdir
2526         rm -f $DIR/$tdir/f0
2527         $LFS setstripe -c 2 $DIR/$tdir
2528
2529         # stop all OSTs to reproduce situation for LU-7975 ticket
2530         for num in $(seq $OSTCOUNT); do
2531                 stop ost$num
2532         done
2533
2534         # open/create f0 with O_LOV_DELAY_CREATE
2535         # truncate f0 to a non-0 size
2536         # close
2537         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2538
2539         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2540         # open/write it again to force delayed layout creation
2541         cat /etc/hosts > $DIR/$tdir/f0 &
2542         catpid=$!
2543
2544         # restart OSTs
2545         for num in $(seq $OSTCOUNT); do
2546                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2547                         error "ost$num failed to start"
2548         done
2549
2550         wait $catpid || error "cat failed"
2551
2552         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2553         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2554                 error "wrong stripecount"
2555
2556 }
2557 run_test 27F "Client resend delayed layout creation with non-zero size"
2558
2559 test_27G() { #LU-10629
2560         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2561                 skip "Need MDS version at least 2.11.51"
2562         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2563         remote_mds_nodsh && skip "remote MDS with nodsh"
2564         local POOL=${POOL:-testpool}
2565         local ostrange="0 0 1"
2566
2567         test_mkdir $DIR/$tdir
2568         pool_add $POOL || error "pool_add failed"
2569         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2570         $LFS setstripe -p $POOL $DIR/$tdir
2571
2572         local pool=$($LFS getstripe -p $DIR/$tdir)
2573
2574         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2575
2576         $LFS setstripe -d $DIR/$tdir
2577
2578         pool=$($LFS getstripe -p $DIR/$tdir)
2579
2580         rmdir $DIR/$tdir
2581
2582         [ -z "$pool" ] || error "'$pool' is not empty"
2583 }
2584 run_test 27G "Clear OST pool from stripe"
2585
2586 test_27H() {
2587         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2588                 skip "Need MDS version newer than 2.11.54"
2589         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2590         test_mkdir $DIR/$tdir
2591         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2592         touch $DIR/$tdir/$tfile
2593         $LFS getstripe -c $DIR/$tdir/$tfile
2594         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2595                 error "two-stripe file doesn't have two stripes"
2596
2597         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2598         $LFS getstripe -y $DIR/$tdir/$tfile
2599         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2600              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2601                 error "expected l_ost_idx: [02]$ not matched"
2602
2603         # make sure ost list has been cleared
2604         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2605         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2606                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2607         touch $DIR/$tdir/f3
2608         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2609 }
2610 run_test 27H "Set specific OSTs stripe"
2611
2612 test_27I() {
2613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2614         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2615         local pool=$TESTNAME
2616         local ostrange="1 1 1"
2617
2618         save_layout_restore_at_exit $MOUNT
2619         $LFS setstripe -c 2 -i 0 $MOUNT
2620         pool_add $pool || error "pool_add failed"
2621         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2622         test_mkdir $DIR/$tdir
2623         $LFS setstripe -p $pool $DIR/$tdir
2624         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2625         $LFS getstripe $DIR/$tdir/$tfile
2626 }
2627 run_test 27I "check that root dir striping does not break parent dir one"
2628
2629 test_27J() {
2630         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
2631                 skip "Need MDS version newer than 2.12.51"
2632
2633         test_mkdir $DIR/$tdir
2634         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2635         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2636
2637         # create foreign file (raw way)
2638         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2639                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2640
2641         # verify foreign file (raw way)
2642         parse_foreign_file -f $DIR/$tdir/$tfile |
2643                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2644                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2645         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2646                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2647         parse_foreign_file -f $DIR/$tdir/$tfile |
2648                 grep "lov_foreign_size: 73" ||
2649                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2650         parse_foreign_file -f $DIR/$tdir/$tfile |
2651                 grep "lov_foreign_type: 1" ||
2652                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2653         parse_foreign_file -f $DIR/$tdir/$tfile |
2654                 grep "lov_foreign_flags: 0x0000DA08" ||
2655                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2656         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2657                 grep "lov_foreign_value: 0x" |
2658                 sed -e 's/lov_foreign_value: 0x//')
2659         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2660         [[ $lov = ${lov2// /} ]] ||
2661                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2662
2663         # create foreign file (lfs + API)
2664         $LFS setstripe --foreign=daos --flags 0xda08 \
2665                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2666                 error "$DIR/$tdir/${tfile}2: create failed"
2667
2668         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2669                 grep "lfm_magic:.*0x0BD70BD0" ||
2670                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2671         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2672         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2673                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2674         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2675                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2676         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2677                 grep "lfm_flags:.*0x0000DA08" ||
2678                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2679         $LFS getstripe $DIR/$tdir/${tfile}2 |
2680                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2681                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2682
2683         # modify striping should fail
2684         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2685                 error "$DIR/$tdir/$tfile: setstripe should fail"
2686         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2687                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2688
2689         # R/W should fail
2690         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2691         cat $DIR/$tdir/${tfile}2 &&
2692                 error "$DIR/$tdir/${tfile}2: read should fail"
2693         cat /etc/passwd > $DIR/$tdir/$tfile &&
2694                 error "$DIR/$tdir/$tfile: write should fail"
2695         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2696                 error "$DIR/$tdir/${tfile}2: write should fail"
2697
2698         # chmod should work
2699         chmod 222 $DIR/$tdir/$tfile ||
2700                 error "$DIR/$tdir/$tfile: chmod failed"
2701         chmod 222 $DIR/$tdir/${tfile}2 ||
2702                 error "$DIR/$tdir/${tfile}2: chmod failed"
2703
2704         # chown should work
2705         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2706                 error "$DIR/$tdir/$tfile: chown failed"
2707         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2708                 error "$DIR/$tdir/${tfile}2: chown failed"
2709
2710         # rename should work
2711         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2712                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2713         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2714                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2715
2716         #remove foreign file
2717         rm $DIR/$tdir/${tfile}.new ||
2718                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2719         rm $DIR/$tdir/${tfile}2.new ||
2720                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2721 }
2722 run_test 27J "basic ops on file with foreign LOV"
2723
2724 test_27K() {
2725         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
2726                 skip "Need MDS version newer than 2.12.49"
2727
2728         test_mkdir $DIR/$tdir
2729         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2730         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2731
2732         # create foreign dir (raw way)
2733         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2734                 error "create_foreign_dir FAILED"
2735
2736         # verify foreign dir (raw way)
2737         parse_foreign_dir -d $DIR/$tdir/$tdir |
2738                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2739                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2740         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2741                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2742         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2743                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2744         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2745                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2746         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2747                 grep "lmv_foreign_value: 0x" |
2748                 sed 's/lmv_foreign_value: 0x//')
2749         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2750                 sed 's/ //g')
2751         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2752
2753         # create foreign dir (lfs + API)
2754         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2755                 $DIR/$tdir/${tdir}2 ||
2756                 error "$DIR/$tdir/${tdir}2: create failed"
2757
2758         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2759                 grep "lfm_magic:.*0x0CD50CD0" ||
2760                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2761         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2762         # - sizeof(lfm_type) - sizeof(lfm_flags)
2763         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2764                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2765         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2766                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2767         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2768                 grep "lfm_flags:.*0x0000DA05" ||
2769                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2770         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2771                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2772                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2773
2774         # file create in dir should fail
2775         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2776         touch $DIR/$tdir/${tdir}2/$tfile &&
2777                 "$DIR/${tdir}2: file create should fail"
2778
2779         # chmod should work
2780         chmod 777 $DIR/$tdir/$tdir ||
2781                 error "$DIR/$tdir: chmod failed"
2782         chmod 777 $DIR/$tdir/${tdir}2 ||
2783                 error "$DIR/${tdir}2: chmod failed"
2784
2785         # chown should work
2786         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2787                 error "$DIR/$tdir: chown failed"
2788         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2789                 error "$DIR/${tdir}2: chown failed"
2790
2791         # rename should work
2792         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2793                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2794         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2795                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2796
2797         #remove foreign dir
2798         rmdir $DIR/$tdir/${tdir}.new ||
2799                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2800         rmdir $DIR/$tdir/${tdir}2.new ||
2801                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2802 }
2803 run_test 27K "basic ops on dir with foreign LMV"
2804
2805 test_27L() {
2806         remote_mds_nodsh && skip "remote MDS with nodsh"
2807
2808         local POOL=${POOL:-$TESTNAME}
2809
2810         pool_add $POOL || error "pool_add failed"
2811
2812         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2813                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2814                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2815 }
2816 run_test 27L "lfs pool_list gives correct pool name"
2817
2818 test_27M() {
2819         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2820                 skip "Need MDS version >= than 2.12.57"
2821         remote_mds_nodsh && skip "remote MDS with nodsh"
2822         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2823
2824         test_mkdir $DIR/$tdir
2825
2826         # Set default striping on directory
2827         $LFS setstripe -C 4 $DIR/$tdir
2828
2829         echo 1 > $DIR/$tdir/${tfile}.1
2830         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2831         local setcount=4
2832         [ $count -eq $setcount ] ||
2833                 error "(1) stripe count $count, should be $setcount"
2834
2835         # Capture existing append_stripe_count setting for restore
2836         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2837         local mdts=$(comma_list $(mdts_nodes))
2838         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2839
2840         local appendcount=$orig_count
2841         echo 1 >> $DIR/$tdir/${tfile}.2_append
2842         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2843         [ $count -eq $appendcount ] ||
2844                 error "(2)stripe count $count, should be $appendcount for append"
2845
2846         # Disable O_APPEND striping, verify it works
2847         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2848
2849         # Should now get the default striping, which is 4
2850         setcount=4
2851         echo 1 >> $DIR/$tdir/${tfile}.3_append
2852         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2853         [ $count -eq $setcount ] ||
2854                 error "(3) stripe count $count, should be $setcount"
2855
2856         # Try changing the stripe count for append files
2857         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2858
2859         # Append striping is now 2 (directory default is still 4)
2860         appendcount=2
2861         echo 1 >> $DIR/$tdir/${tfile}.4_append
2862         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2863         [ $count -eq $appendcount ] ||
2864                 error "(4) stripe count $count, should be $appendcount for append"
2865
2866         # Test append stripe count of -1
2867         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2868         appendcount=$OSTCOUNT
2869         echo 1 >> $DIR/$tdir/${tfile}.5
2870         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2871         [ $count -eq $appendcount ] ||
2872                 error "(5) stripe count $count, should be $appendcount for append"
2873
2874         # Set append striping back to default of 1
2875         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2876
2877         # Try a new default striping, PFL + DOM
2878         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2879
2880         # Create normal DOM file, DOM returns stripe count == 0
2881         setcount=0
2882         touch $DIR/$tdir/${tfile}.6
2883         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2884         [ $count -eq $setcount ] ||
2885                 error "(6) stripe count $count, should be $setcount"
2886
2887         # Show
2888         appendcount=1
2889         echo 1 >> $DIR/$tdir/${tfile}.7_append
2890         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2891         [ $count -eq $appendcount ] ||
2892                 error "(7) stripe count $count, should be $appendcount for append"
2893
2894         # Clean up DOM layout
2895         $LFS setstripe -d $DIR/$tdir
2896
2897         # Now test that append striping works when layout is from root
2898         $LFS setstripe -c 2 $MOUNT
2899         # Make a special directory for this
2900         mkdir $DIR/${tdir}/${tdir}.2
2901         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2902
2903         # Verify for normal file
2904         setcount=2
2905         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2906         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2907         [ $count -eq $setcount ] ||
2908                 error "(8) stripe count $count, should be $setcount"
2909
2910         appendcount=1
2911         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2912         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2913         [ $count -eq $appendcount ] ||
2914                 error "(9) stripe count $count, should be $appendcount for append"
2915
2916         # Now test O_APPEND striping with pools
2917         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2918         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2919
2920         # Create the pool
2921         pool_add $TESTNAME || error "pool creation failed"
2922         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2923
2924         echo 1 >> $DIR/$tdir/${tfile}.10_append
2925
2926         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2927         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2928
2929         # Check that count is still correct
2930         appendcount=1
2931         echo 1 >> $DIR/$tdir/${tfile}.11_append
2932         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2933         [ $count -eq $appendcount ] ||
2934                 error "(11) stripe count $count, should be $appendcount for append"
2935
2936         # Disable O_APPEND stripe count, verify pool works separately
2937         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2938
2939         echo 1 >> $DIR/$tdir/${tfile}.12_append
2940
2941         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
2942         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
2943
2944         # Remove pool setting, verify it's not applied
2945         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
2946
2947         echo 1 >> $DIR/$tdir/${tfile}.13_append
2948
2949         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
2950         [ "$pool" = "" ] || error "(13) pool found: $pool"
2951 }
2952 run_test 27M "test O_APPEND striping"
2953
2954 test_27N() {
2955         combined_mgs_mds && skip "needs separate MGS/MDT"
2956
2957         pool_add $TESTNAME || error "pool_add failed"
2958         do_facet mgs "$LCTL pool_list $FSNAME" |
2959                 grep -Fx "${FSNAME}.${TESTNAME}" ||
2960                 error "lctl pool_list on MGS failed"
2961 }
2962 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
2963
2964 # createtest also checks that device nodes are created and
2965 # then visible correctly (#2091)
2966 test_28() { # bug 2091
2967         test_mkdir $DIR/d28
2968         $CREATETEST $DIR/d28/ct || error "createtest failed"
2969 }
2970 run_test 28 "create/mknod/mkdir with bad file types ============"
2971
2972 test_29() {
2973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2974
2975         sync; sleep 1; sync # flush out any dirty pages from previous tests
2976         cancel_lru_locks
2977         test_mkdir $DIR/d29
2978         touch $DIR/d29/foo
2979         log 'first d29'
2980         ls -l $DIR/d29
2981
2982         declare -i LOCKCOUNTORIG=0
2983         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2984                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2985         done
2986         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2987
2988         declare -i LOCKUNUSEDCOUNTORIG=0
2989         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2990                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2991         done
2992
2993         log 'second d29'
2994         ls -l $DIR/d29
2995         log 'done'
2996
2997         declare -i LOCKCOUNTCURRENT=0
2998         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2999                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3000         done
3001
3002         declare -i LOCKUNUSEDCOUNTCURRENT=0
3003         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3004                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3005         done
3006
3007         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3008                 $LCTL set_param -n ldlm.dump_namespaces ""
3009                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3010                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3011                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3012                 return 2
3013         fi
3014         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3015                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3016                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3017                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3018                 return 3
3019         fi
3020 }
3021 run_test 29 "IT_GETATTR regression  ============================"
3022
3023 test_30a() { # was test_30
3024         cp $(which ls) $DIR || cp /bin/ls $DIR
3025         $DIR/ls / || error "Can't execute binary from lustre"
3026         rm $DIR/ls
3027 }
3028 run_test 30a "execute binary from Lustre (execve) =============="
3029
3030 test_30b() {
3031         cp `which ls` $DIR || cp /bin/ls $DIR
3032         chmod go+rx $DIR/ls
3033         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3034         rm $DIR/ls
3035 }
3036 run_test 30b "execute binary from Lustre as non-root ==========="
3037
3038 test_30c() { # b=22376
3039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3040
3041         cp `which ls` $DIR || cp /bin/ls $DIR
3042         chmod a-rw $DIR/ls
3043         cancel_lru_locks mdc
3044         cancel_lru_locks osc
3045         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3046         rm -f $DIR/ls
3047 }
3048 run_test 30c "execute binary from Lustre without read perms ===="
3049
3050 test_31a() {
3051         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3052         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3053 }
3054 run_test 31a "open-unlink file =================================="
3055
3056 test_31b() {
3057         touch $DIR/f31 || error "touch $DIR/f31 failed"
3058         ln $DIR/f31 $DIR/f31b || error "ln failed"
3059         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3060         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3061 }
3062 run_test 31b "unlink file with multiple links while open ======="
3063
3064 test_31c() {
3065         touch $DIR/f31 || error "touch $DIR/f31 failed"
3066         ln $DIR/f31 $DIR/f31c || error "ln failed"
3067         multiop_bg_pause $DIR/f31 O_uc ||
3068                 error "multiop_bg_pause for $DIR/f31 failed"
3069         MULTIPID=$!
3070         $MULTIOP $DIR/f31c Ouc
3071         kill -USR1 $MULTIPID
3072         wait $MULTIPID
3073 }
3074 run_test 31c "open-unlink file with multiple links ============="
3075
3076 test_31d() {
3077         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3078         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3079 }
3080 run_test 31d "remove of open directory ========================="
3081
3082 test_31e() { # bug 2904
3083         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3084 }
3085 run_test 31e "remove of open non-empty directory ==============="
3086
3087 test_31f() { # bug 4554
3088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3089
3090         set -vx
3091         test_mkdir $DIR/d31f
3092         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3093         cp /etc/hosts $DIR/d31f
3094         ls -l $DIR/d31f
3095         $LFS getstripe $DIR/d31f/hosts
3096         multiop_bg_pause $DIR/d31f D_c || return 1
3097         MULTIPID=$!
3098
3099         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3100         test_mkdir $DIR/d31f
3101         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3102         cp /etc/hosts $DIR/d31f
3103         ls -l $DIR/d31f
3104         $LFS getstripe $DIR/d31f/hosts
3105         multiop_bg_pause $DIR/d31f D_c || return 1
3106         MULTIPID2=$!
3107
3108         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3109         wait $MULTIPID || error "first opendir $MULTIPID failed"
3110
3111         sleep 6
3112
3113         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3114         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3115         set +vx
3116 }
3117 run_test 31f "remove of open directory with open-unlink file ==="
3118
3119 test_31g() {
3120         echo "-- cross directory link --"
3121         test_mkdir -c1 $DIR/${tdir}ga
3122         test_mkdir -c1 $DIR/${tdir}gb
3123         touch $DIR/${tdir}ga/f
3124         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3125         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3126         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3127         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3128         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3129 }
3130 run_test 31g "cross directory link==============="
3131
3132 test_31h() {
3133         echo "-- cross directory link --"
3134         test_mkdir -c1 $DIR/${tdir}
3135         test_mkdir -c1 $DIR/${tdir}/dir
3136         touch $DIR/${tdir}/f
3137         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3138         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3139         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3140         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3141         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3142 }
3143 run_test 31h "cross directory link under child==============="
3144
3145 test_31i() {
3146         echo "-- cross directory link --"
3147         test_mkdir -c1 $DIR/$tdir
3148         test_mkdir -c1 $DIR/$tdir/dir
3149         touch $DIR/$tdir/dir/f
3150         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3151         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3152         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3153         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3154         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3155 }
3156 run_test 31i "cross directory link under parent==============="
3157
3158 test_31j() {
3159         test_mkdir -c1 -p $DIR/$tdir
3160         test_mkdir -c1 -p $DIR/$tdir/dir1
3161         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3162         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3163         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3164         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3165         return 0
3166 }
3167 run_test 31j "link for directory==============="
3168
3169 test_31k() {
3170         test_mkdir -c1 -p $DIR/$tdir
3171         touch $DIR/$tdir/s
3172         touch $DIR/$tdir/exist
3173         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3174         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3175         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3176         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3177         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3178         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3179         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3180         return 0
3181 }
3182 run_test 31k "link to file: the same, non-existing, dir==============="
3183
3184 test_31m() {
3185         mkdir $DIR/d31m
3186         touch $DIR/d31m/s
3187         mkdir $DIR/d31m2
3188         touch $DIR/d31m2/exist
3189         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3190         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3191         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3192         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3193         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3194         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3195         return 0
3196 }
3197 run_test 31m "link to file: the same, non-existing, dir==============="
3198
3199 test_31n() {
3200         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3201         nlink=$(stat --format=%h $DIR/$tfile)
3202         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3203         local fd=$(free_fd)
3204         local cmd="exec $fd<$DIR/$tfile"
3205         eval $cmd
3206         cmd="exec $fd<&-"
3207         trap "eval $cmd" EXIT
3208         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3209         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3210         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3211         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3212         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3213         eval $cmd
3214 }
3215 run_test 31n "check link count of unlinked file"
3216
3217 link_one() {
3218         local tempfile=$(mktemp $1_XXXXXX)
3219         mlink $tempfile $1 2> /dev/null &&
3220                 echo "$BASHPID: link $tempfile to $1 succeeded"
3221         munlink $tempfile
3222 }
3223
3224 test_31o() { # LU-2901
3225         test_mkdir $DIR/$tdir
3226         for LOOP in $(seq 100); do
3227                 rm -f $DIR/$tdir/$tfile*
3228                 for THREAD in $(seq 8); do
3229                         link_one $DIR/$tdir/$tfile.$LOOP &
3230                 done
3231                 wait
3232                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3233                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3234                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3235                         break || true
3236         done
3237 }
3238 run_test 31o "duplicate hard links with same filename"
3239
3240 test_31p() {
3241         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3242
3243         test_mkdir $DIR/$tdir
3244         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3245         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3246
3247         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3248                 error "open unlink test1 failed"
3249         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3250                 error "open unlink test2 failed"
3251
3252         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3253                 error "test1 still exists"
3254         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3255                 error "test2 still exists"
3256 }
3257 run_test 31p "remove of open striped directory"
3258
3259 cleanup_test32_mount() {
3260         local rc=0
3261         trap 0
3262         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3263         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3264         losetup -d $loopdev || true
3265         rm -rf $DIR/$tdir
3266         return $rc
3267 }
3268
3269 test_32a() {
3270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3271
3272         echo "== more mountpoints and symlinks ================="
3273         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3274         trap cleanup_test32_mount EXIT
3275         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3276         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3277                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3278         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3279                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3280         cleanup_test32_mount
3281 }
3282 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3283
3284 test_32b() {
3285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3286
3287         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3288         trap cleanup_test32_mount EXIT
3289         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3290         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3291                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3292         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3293                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3294         cleanup_test32_mount
3295 }
3296 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3297
3298 test_32c() {
3299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3300
3301         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3302         trap cleanup_test32_mount EXIT
3303         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3304         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3305                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3306         test_mkdir -p $DIR/$tdir/d2/test_dir
3307         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3308                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3309         cleanup_test32_mount
3310 }
3311 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3312
3313 test_32d() {
3314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3315
3316         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3317         trap cleanup_test32_mount EXIT
3318         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3319         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3320                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3321         test_mkdir -p $DIR/$tdir/d2/test_dir
3322         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3323                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3324         cleanup_test32_mount
3325 }
3326 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3327
3328 test_32e() {
3329         rm -fr $DIR/$tdir
3330         test_mkdir -p $DIR/$tdir/tmp
3331         local tmp_dir=$DIR/$tdir/tmp
3332         ln -s $DIR/$tdir $tmp_dir/symlink11
3333         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3334         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3335         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3336 }
3337 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3338
3339 test_32f() {
3340         rm -fr $DIR/$tdir
3341         test_mkdir -p $DIR/$tdir/tmp
3342         local tmp_dir=$DIR/$tdir/tmp
3343         ln -s $DIR/$tdir $tmp_dir/symlink11
3344         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3345         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3346         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3347 }
3348 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3349
3350 test_32g() {
3351         local tmp_dir=$DIR/$tdir/tmp
3352         test_mkdir -p $tmp_dir
3353         test_mkdir $DIR/${tdir}2
3354         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3355         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3356         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3357         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3358         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3359         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3360 }
3361 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3362
3363 test_32h() {
3364         rm -fr $DIR/$tdir $DIR/${tdir}2
3365         tmp_dir=$DIR/$tdir/tmp
3366         test_mkdir -p $tmp_dir
3367         test_mkdir $DIR/${tdir}2
3368         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3369         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3370         ls $tmp_dir/symlink12 || error "listing symlink12"
3371         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3372 }
3373 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3374
3375 test_32i() {
3376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3377
3378         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3379         trap cleanup_test32_mount EXIT
3380         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3381         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3382                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3383         touch $DIR/$tdir/test_file
3384         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3385                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3386         cleanup_test32_mount
3387 }
3388 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3389
3390 test_32j() {
3391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3392
3393         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3394         trap cleanup_test32_mount EXIT
3395         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3396         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3397                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3398         touch $DIR/$tdir/test_file
3399         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3400                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3401         cleanup_test32_mount
3402 }
3403 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3404
3405 test_32k() {
3406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3407
3408         rm -fr $DIR/$tdir
3409         trap cleanup_test32_mount EXIT
3410         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3411         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3412                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3413         test_mkdir -p $DIR/$tdir/d2
3414         touch $DIR/$tdir/d2/test_file || error "touch failed"
3415         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3416                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3417         cleanup_test32_mount
3418 }
3419 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3420
3421 test_32l() {
3422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3423
3424         rm -fr $DIR/$tdir
3425         trap cleanup_test32_mount EXIT
3426         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3427         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3428                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3429         test_mkdir -p $DIR/$tdir/d2
3430         touch $DIR/$tdir/d2/test_file || error "touch failed"
3431         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3432                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3433         cleanup_test32_mount
3434 }
3435 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3436
3437 test_32m() {
3438         rm -fr $DIR/d32m
3439         test_mkdir -p $DIR/d32m/tmp
3440         TMP_DIR=$DIR/d32m/tmp
3441         ln -s $DIR $TMP_DIR/symlink11
3442         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3443         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3444                 error "symlink11 not a link"
3445         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3446                 error "symlink01 not a link"
3447 }
3448 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3449
3450 test_32n() {
3451         rm -fr $DIR/d32n
3452         test_mkdir -p $DIR/d32n/tmp
3453         TMP_DIR=$DIR/d32n/tmp
3454         ln -s $DIR $TMP_DIR/symlink11
3455         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3456         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3457         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3458 }
3459 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3460
3461 test_32o() {
3462         touch $DIR/$tfile
3463         test_mkdir -p $DIR/d32o/tmp
3464         TMP_DIR=$DIR/d32o/tmp
3465         ln -s $DIR/$tfile $TMP_DIR/symlink12
3466         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3467         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3468                 error "symlink12 not a link"
3469         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3470         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3471                 error "$DIR/d32o/tmp/symlink12 not file type"
3472         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3473                 error "$DIR/d32o/symlink02 not file type"
3474 }
3475 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3476
3477 test_32p() {
3478         log 32p_1
3479         rm -fr $DIR/d32p
3480         log 32p_2
3481         rm -f $DIR/$tfile
3482         log 32p_3
3483         touch $DIR/$tfile
3484         log 32p_4
3485         test_mkdir -p $DIR/d32p/tmp
3486         log 32p_5
3487         TMP_DIR=$DIR/d32p/tmp
3488         log 32p_6
3489         ln -s $DIR/$tfile $TMP_DIR/symlink12
3490         log 32p_7
3491         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3492         log 32p_8
3493         cat $DIR/d32p/tmp/symlink12 ||
3494                 error "Can't open $DIR/d32p/tmp/symlink12"
3495         log 32p_9
3496         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3497         log 32p_10
3498 }
3499 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3500
3501 test_32q() {
3502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3503
3504         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3505         trap cleanup_test32_mount EXIT
3506         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3507         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3508         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3509                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3510         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3511         cleanup_test32_mount
3512 }
3513 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3514
3515 test_32r() {
3516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3517
3518         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3519         trap cleanup_test32_mount EXIT
3520         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3521         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3522         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3523                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3524         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3525         cleanup_test32_mount
3526 }
3527 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3528
3529 test_33aa() {
3530         rm -f $DIR/$tfile
3531         touch $DIR/$tfile
3532         chmod 444 $DIR/$tfile
3533         chown $RUNAS_ID $DIR/$tfile
3534         log 33_1
3535         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3536         log 33_2
3537 }
3538 run_test 33aa "write file with mode 444 (should return error)"
3539
3540 test_33a() {
3541         rm -fr $DIR/$tdir
3542         test_mkdir $DIR/$tdir
3543         chown $RUNAS_ID $DIR/$tdir
3544         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3545                 error "$RUNAS create $tdir/$tfile failed"
3546         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3547                 error "open RDWR" || true
3548 }
3549 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3550
3551 test_33b() {
3552         rm -fr $DIR/$tdir
3553         test_mkdir $DIR/$tdir
3554         chown $RUNAS_ID $DIR/$tdir
3555         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3556 }
3557 run_test 33b "test open file with malformed flags (No panic)"
3558
3559 test_33c() {
3560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3561         remote_ost_nodsh && skip "remote OST with nodsh"
3562
3563         local ostnum
3564         local ostname
3565         local write_bytes
3566         local all_zeros
3567
3568         all_zeros=:
3569         rm -fr $DIR/$tdir
3570         test_mkdir $DIR/$tdir
3571         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3572
3573         sync
3574         for ostnum in $(seq $OSTCOUNT); do
3575                 # test-framework's OST numbering is one-based, while Lustre's
3576                 # is zero-based
3577                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3578                 # Parsing llobdstat's output sucks; we could grep the /proc
3579                 # path, but that's likely to not be as portable as using the
3580                 # llobdstat utility.  So we parse lctl output instead.
3581                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3582                         obdfilter/$ostname/stats |
3583                         awk '/^write_bytes/ {print $7}' )
3584                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3585                 if (( ${write_bytes:-0} > 0 ))
3586                 then
3587                         all_zeros=false
3588                         break;
3589                 fi
3590         done
3591
3592         $all_zeros || return 0
3593
3594         # Write four bytes
3595         echo foo > $DIR/$tdir/bar
3596         # Really write them
3597         sync
3598
3599         # Total up write_bytes after writing.  We'd better find non-zeros.
3600         for ostnum in $(seq $OSTCOUNT); do
3601                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3602                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3603                         obdfilter/$ostname/stats |
3604                         awk '/^write_bytes/ {print $7}' )
3605                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3606                 if (( ${write_bytes:-0} > 0 ))
3607                 then
3608                         all_zeros=false
3609                         break;
3610                 fi
3611         done
3612
3613         if $all_zeros
3614         then
3615                 for ostnum in $(seq $OSTCOUNT); do
3616                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3617                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3618                         do_facet ost$ostnum lctl get_param -n \
3619                                 obdfilter/$ostname/stats
3620                 done
3621                 error "OST not keeping write_bytes stats (b22312)"
3622         fi
3623 }
3624 run_test 33c "test llobdstat and write_bytes"
3625
3626 test_33d() {
3627         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3629
3630         local MDTIDX=1
3631         local remote_dir=$DIR/$tdir/remote_dir
3632
3633         test_mkdir $DIR/$tdir
3634         $LFS mkdir -i $MDTIDX $remote_dir ||
3635                 error "create remote directory failed"
3636
3637         touch $remote_dir/$tfile
3638         chmod 444 $remote_dir/$tfile
3639         chown $RUNAS_ID $remote_dir/$tfile
3640
3641         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3642
3643         chown $RUNAS_ID $remote_dir
3644         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3645                                         error "create" || true
3646         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3647                                     error "open RDWR" || true
3648         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3649 }
3650 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3651
3652 test_33e() {
3653         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3654
3655         mkdir $DIR/$tdir
3656
3657         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3658         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3659         mkdir $DIR/$tdir/local_dir
3660
3661         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3662         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3663         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3664
3665         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3666                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3667
3668         rmdir $DIR/$tdir/* || error "rmdir failed"
3669
3670         umask 777
3671         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3672         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3673         mkdir $DIR/$tdir/local_dir
3674
3675         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3676         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3677         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3678
3679         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3680                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3681
3682         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3683
3684         umask 000
3685         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3686         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3687         mkdir $DIR/$tdir/local_dir
3688
3689         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3690         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3691         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3692
3693         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3694                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3695 }
3696 run_test 33e "mkdir and striped directory should have same mode"
3697
3698 cleanup_33f() {
3699         trap 0
3700         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3701 }
3702
3703 test_33f() {
3704         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3705         remote_mds_nodsh && skip "remote MDS with nodsh"
3706
3707         mkdir $DIR/$tdir
3708         chmod go+rwx $DIR/$tdir
3709         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3710         trap cleanup_33f EXIT
3711
3712         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3713                 error "cannot create striped directory"
3714
3715         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3716                 error "cannot create files in striped directory"
3717
3718         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3719                 error "cannot remove files in striped directory"
3720
3721         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3722                 error "cannot remove striped directory"
3723
3724         cleanup_33f
3725 }
3726 run_test 33f "nonroot user can create, access, and remove a striped directory"
3727
3728 test_33g() {
3729         mkdir -p $DIR/$tdir/dir2
3730
3731         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3732         echo $err
3733         [[ $err =~ "exists" ]] || error "Not exists error"
3734 }
3735 run_test 33g "nonroot user create already existing root created file"
3736
3737 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3738 test_34a() {
3739         rm -f $DIR/f34
3740         $MCREATE $DIR/f34 || error "mcreate failed"
3741         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3742                 error "getstripe failed"
3743         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3744         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3745                 error "getstripe failed"
3746         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3747                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3748 }
3749 run_test 34a "truncate file that has not been opened ==========="
3750
3751 test_34b() {
3752         [ ! -f $DIR/f34 ] && test_34a
3753         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3754                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3755         $OPENFILE -f O_RDONLY $DIR/f34
3756         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3757                 error "getstripe failed"
3758         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3759                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3760 }
3761 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3762
3763 test_34c() {
3764         [ ! -f $DIR/f34 ] && test_34a
3765         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3766                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3767         $OPENFILE -f O_RDWR $DIR/f34
3768         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3769                 error "$LFS getstripe failed"
3770         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3771                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3772 }
3773 run_test 34c "O_RDWR opening file-with-size works =============="
3774
3775 test_34d() {
3776         [ ! -f $DIR/f34 ] && test_34a
3777         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3778                 error "dd failed"
3779         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3780                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3781         rm $DIR/f34
3782 }
3783 run_test 34d "write to sparse file ============================="
3784
3785 test_34e() {
3786         rm -f $DIR/f34e
3787         $MCREATE $DIR/f34e || error "mcreate failed"
3788         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3789         $CHECKSTAT -s 1000 $DIR/f34e ||
3790                 error "Size of $DIR/f34e not equal to 1000 bytes"
3791         $OPENFILE -f O_RDWR $DIR/f34e
3792         $CHECKSTAT -s 1000 $DIR/f34e ||
3793                 error "Size of $DIR/f34e not equal to 1000 bytes"
3794 }
3795 run_test 34e "create objects, some with size and some without =="
3796
3797 test_34f() { # bug 6242, 6243
3798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3799
3800         SIZE34F=48000
3801         rm -f $DIR/f34f
3802         $MCREATE $DIR/f34f || error "mcreate failed"
3803         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3804         dd if=$DIR/f34f of=$TMP/f34f
3805         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3806         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3807         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3808         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3809         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3810 }
3811 run_test 34f "read from a file with no objects until EOF ======="
3812
3813 test_34g() {
3814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3815
3816         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3817                 error "dd failed"
3818         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3819         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3820                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3821         cancel_lru_locks osc
3822         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3823                 error "wrong size after lock cancel"
3824
3825         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3826         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3827                 error "expanding truncate failed"
3828         cancel_lru_locks osc
3829         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3830                 error "wrong expanded size after lock cancel"
3831 }
3832 run_test 34g "truncate long file ==============================="
3833
3834 test_34h() {
3835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3836
3837         local gid=10
3838         local sz=1000
3839
3840         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3841         sync # Flush the cache so that multiop below does not block on cache
3842              # flush when getting the group lock
3843         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3844         MULTIPID=$!
3845
3846         # Since just timed wait is not good enough, let's do a sync write
3847         # that way we are sure enough time for a roundtrip + processing
3848         # passed + 2 seconds of extra margin.
3849         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3850         rm $DIR/${tfile}-1
3851         sleep 2
3852
3853         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3854                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3855                 kill -9 $MULTIPID
3856         fi
3857         wait $MULTIPID
3858         local nsz=`stat -c %s $DIR/$tfile`
3859         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3860 }
3861 run_test 34h "ftruncate file under grouplock should not block"
3862
3863 test_35a() {
3864         cp /bin/sh $DIR/f35a
3865         chmod 444 $DIR/f35a
3866         chown $RUNAS_ID $DIR/f35a
3867         $RUNAS $DIR/f35a && error || true
3868         rm $DIR/f35a
3869 }
3870 run_test 35a "exec file with mode 444 (should return and not leak)"
3871
3872 test_36a() {
3873         rm -f $DIR/f36
3874         utime $DIR/f36 || error "utime failed for MDS"
3875 }
3876 run_test 36a "MDS utime check (mknod, utime)"
3877
3878 test_36b() {
3879         echo "" > $DIR/f36
3880         utime $DIR/f36 || error "utime failed for OST"
3881 }
3882 run_test 36b "OST utime check (open, utime)"
3883
3884 test_36c() {
3885         rm -f $DIR/d36/f36
3886         test_mkdir $DIR/d36
3887         chown $RUNAS_ID $DIR/d36
3888         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3889 }
3890 run_test 36c "non-root MDS utime check (mknod, utime)"
3891
3892 test_36d() {
3893         [ ! -d $DIR/d36 ] && test_36c
3894         echo "" > $DIR/d36/f36
3895         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3896 }
3897 run_test 36d "non-root OST utime check (open, utime)"
3898
3899 test_36e() {
3900         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3901
3902         test_mkdir $DIR/$tdir
3903         touch $DIR/$tdir/$tfile
3904         $RUNAS utime $DIR/$tdir/$tfile &&
3905                 error "utime worked, expected failure" || true
3906 }
3907 run_test 36e "utime on non-owned file (should return error)"
3908
3909 subr_36fh() {
3910         local fl="$1"
3911         local LANG_SAVE=$LANG
3912         local LC_LANG_SAVE=$LC_LANG
3913         export LANG=C LC_LANG=C # for date language
3914
3915         DATESTR="Dec 20  2000"
3916         test_mkdir $DIR/$tdir
3917         lctl set_param fail_loc=$fl
3918         date; date +%s
3919         cp /etc/hosts $DIR/$tdir/$tfile
3920         sync & # write RPC generated with "current" inode timestamp, but delayed
3921         sleep 1
3922         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3923         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3924         cancel_lru_locks $OSC
3925         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3926         date; date +%s
3927         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3928                 echo "BEFORE: $LS_BEFORE" && \
3929                 echo "AFTER : $LS_AFTER" && \
3930                 echo "WANT  : $DATESTR" && \
3931                 error "$DIR/$tdir/$tfile timestamps changed" || true
3932
3933         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3934 }
3935
3936 test_36f() {
3937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3938
3939         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3940         subr_36fh "0x80000214"
3941 }
3942 run_test 36f "utime on file racing with OST BRW write =========="
3943
3944 test_36g() {
3945         remote_ost_nodsh && skip "remote OST with nodsh"
3946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3947         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3948                 skip "Need MDS version at least 2.12.51"
3949
3950         local fmd_max_age
3951         local fmd
3952         local facet="ost1"
3953         local tgt="obdfilter"
3954
3955         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3956
3957         test_mkdir $DIR/$tdir
3958         fmd_max_age=$(do_facet $facet \
3959                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3960                 head -n 1")
3961
3962         echo "FMD max age: ${fmd_max_age}s"
3963         touch $DIR/$tdir/$tfile
3964         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3965                 gawk '{cnt=cnt+$1}  END{print cnt}')
3966         echo "FMD before: $fmd"
3967         [[ $fmd == 0 ]] &&
3968                 error "FMD wasn't create by touch"
3969         sleep $((fmd_max_age + 12))
3970         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3971                 gawk '{cnt=cnt+$1}  END{print cnt}')
3972         echo "FMD after: $fmd"
3973         [[ $fmd == 0 ]] ||
3974                 error "FMD wasn't expired by ping"
3975 }
3976 run_test 36g "FMD cache expiry ====================="
3977
3978 test_36h() {
3979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3980
3981         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3982         subr_36fh "0x80000227"
3983 }
3984 run_test 36h "utime on file racing with OST BRW write =========="
3985
3986 test_36i() {
3987         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3988
3989         test_mkdir $DIR/$tdir
3990         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3991
3992         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3993         local new_mtime=$((mtime + 200))
3994
3995         #change Modify time of striped dir
3996         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3997                         error "change mtime failed"
3998
3999         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4000
4001         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4002 }
4003 run_test 36i "change mtime on striped directory"
4004
4005 # test_37 - duplicate with tests 32q 32r
4006
4007 test_38() {
4008         local file=$DIR/$tfile
4009         touch $file
4010         openfile -f O_DIRECTORY $file
4011         local RC=$?
4012         local ENOTDIR=20
4013         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4014         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4015 }
4016 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4017
4018 test_39a() { # was test_39
4019         touch $DIR/$tfile
4020         touch $DIR/${tfile}2
4021 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4022 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4023 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4024         sleep 2
4025         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4026         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4027                 echo "mtime"
4028                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4029                 echo "atime"
4030                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4031                 echo "ctime"
4032                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4033                 error "O_TRUNC didn't change timestamps"
4034         fi
4035 }
4036 run_test 39a "mtime changed on create"
4037
4038 test_39b() {
4039         test_mkdir -c1 $DIR/$tdir
4040         cp -p /etc/passwd $DIR/$tdir/fopen
4041         cp -p /etc/passwd $DIR/$tdir/flink
4042         cp -p /etc/passwd $DIR/$tdir/funlink
4043         cp -p /etc/passwd $DIR/$tdir/frename
4044         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4045
4046         sleep 1
4047         echo "aaaaaa" >> $DIR/$tdir/fopen
4048         echo "aaaaaa" >> $DIR/$tdir/flink
4049         echo "aaaaaa" >> $DIR/$tdir/funlink
4050         echo "aaaaaa" >> $DIR/$tdir/frename
4051
4052         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4053         local link_new=`stat -c %Y $DIR/$tdir/flink`
4054         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4055         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4056
4057         cat $DIR/$tdir/fopen > /dev/null
4058         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4059         rm -f $DIR/$tdir/funlink2
4060         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4061
4062         for (( i=0; i < 2; i++ )) ; do
4063                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4064                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4065                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4066                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4067
4068                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4069                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4070                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4071                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4072
4073                 cancel_lru_locks $OSC
4074                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4075         done
4076 }
4077 run_test 39b "mtime change on open, link, unlink, rename  ======"
4078
4079 # this should be set to past
4080 TEST_39_MTIME=`date -d "1 year ago" +%s`
4081
4082 # bug 11063
4083 test_39c() {
4084         touch $DIR1/$tfile
4085         sleep 2
4086         local mtime0=`stat -c %Y $DIR1/$tfile`
4087
4088         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4089         local mtime1=`stat -c %Y $DIR1/$tfile`
4090         [ "$mtime1" = $TEST_39_MTIME ] || \
4091                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4092
4093         local d1=`date +%s`
4094         echo hello >> $DIR1/$tfile
4095         local d2=`date +%s`
4096         local mtime2=`stat -c %Y $DIR1/$tfile`
4097         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4098                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4099
4100         mv $DIR1/$tfile $DIR1/$tfile-1
4101
4102         for (( i=0; i < 2; i++ )) ; do
4103                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4104                 [ "$mtime2" = "$mtime3" ] || \
4105                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4106
4107                 cancel_lru_locks $OSC
4108                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4109         done
4110 }
4111 run_test 39c "mtime change on rename ==========================="
4112
4113 # bug 21114
4114 test_39d() {
4115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4116
4117         touch $DIR1/$tfile
4118         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4119
4120         for (( i=0; i < 2; i++ )) ; do
4121                 local mtime=`stat -c %Y $DIR1/$tfile`
4122                 [ $mtime = $TEST_39_MTIME ] || \
4123                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4124
4125                 cancel_lru_locks $OSC
4126                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4127         done
4128 }
4129 run_test 39d "create, utime, stat =============================="
4130
4131 # bug 21114
4132 test_39e() {
4133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4134
4135         touch $DIR1/$tfile
4136         local mtime1=`stat -c %Y $DIR1/$tfile`
4137
4138         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4139
4140         for (( i=0; i < 2; i++ )) ; do
4141                 local mtime2=`stat -c %Y $DIR1/$tfile`
4142                 [ $mtime2 = $TEST_39_MTIME ] || \
4143                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4144
4145                 cancel_lru_locks $OSC
4146                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4147         done
4148 }
4149 run_test 39e "create, stat, utime, stat ========================"
4150
4151 # bug 21114
4152 test_39f() {
4153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4154
4155         touch $DIR1/$tfile
4156         mtime1=`stat -c %Y $DIR1/$tfile`
4157
4158         sleep 2
4159         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4160
4161         for (( i=0; i < 2; i++ )) ; do
4162                 local mtime2=`stat -c %Y $DIR1/$tfile`
4163                 [ $mtime2 = $TEST_39_MTIME ] || \
4164                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4165
4166                 cancel_lru_locks $OSC
4167                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4168         done
4169 }
4170 run_test 39f "create, stat, sleep, utime, stat ================="
4171
4172 # bug 11063
4173 test_39g() {
4174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4175
4176         echo hello >> $DIR1/$tfile
4177         local mtime1=`stat -c %Y $DIR1/$tfile`
4178
4179         sleep 2
4180         chmod o+r $DIR1/$tfile
4181
4182         for (( i=0; i < 2; i++ )) ; do
4183                 local mtime2=`stat -c %Y $DIR1/$tfile`
4184                 [ "$mtime1" = "$mtime2" ] || \
4185                         error "lost mtime: $mtime2, should be $mtime1"
4186
4187                 cancel_lru_locks $OSC
4188                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4189         done
4190 }
4191 run_test 39g "write, chmod, stat ==============================="
4192
4193 # bug 11063
4194 test_39h() {
4195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4196
4197         touch $DIR1/$tfile
4198         sleep 1
4199
4200         local d1=`date`
4201         echo hello >> $DIR1/$tfile
4202         local mtime1=`stat -c %Y $DIR1/$tfile`
4203
4204         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4205         local d2=`date`
4206         if [ "$d1" != "$d2" ]; then
4207                 echo "write and touch not within one second"
4208         else
4209                 for (( i=0; i < 2; i++ )) ; do
4210                         local mtime2=`stat -c %Y $DIR1/$tfile`
4211                         [ "$mtime2" = $TEST_39_MTIME ] || \
4212                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4213
4214                         cancel_lru_locks $OSC
4215                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4216                 done
4217         fi
4218 }
4219 run_test 39h "write, utime within one second, stat ============="
4220
4221 test_39i() {
4222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4223
4224         touch $DIR1/$tfile
4225         sleep 1
4226
4227         echo hello >> $DIR1/$tfile
4228         local mtime1=`stat -c %Y $DIR1/$tfile`
4229
4230         mv $DIR1/$tfile $DIR1/$tfile-1
4231
4232         for (( i=0; i < 2; i++ )) ; do
4233                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4234
4235                 [ "$mtime1" = "$mtime2" ] || \
4236                         error "lost mtime: $mtime2, should be $mtime1"
4237
4238                 cancel_lru_locks $OSC
4239                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4240         done
4241 }
4242 run_test 39i "write, rename, stat =============================="
4243
4244 test_39j() {
4245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4246
4247         start_full_debug_logging
4248         touch $DIR1/$tfile
4249         sleep 1
4250
4251         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4252         lctl set_param fail_loc=0x80000412
4253         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4254                 error "multiop failed"
4255         local multipid=$!
4256         local mtime1=`stat -c %Y $DIR1/$tfile`
4257
4258         mv $DIR1/$tfile $DIR1/$tfile-1
4259
4260         kill -USR1 $multipid
4261         wait $multipid || error "multiop close failed"
4262
4263         for (( i=0; i < 2; i++ )) ; do
4264                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4265                 [ "$mtime1" = "$mtime2" ] ||
4266                         error "mtime is lost on close: $mtime2, " \
4267                               "should be $mtime1"
4268
4269                 cancel_lru_locks $OSC
4270                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4271         done
4272         lctl set_param fail_loc=0
4273         stop_full_debug_logging
4274 }
4275 run_test 39j "write, rename, close, stat ======================="
4276
4277 test_39k() {
4278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4279
4280         touch $DIR1/$tfile
4281         sleep 1
4282
4283         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4284         local multipid=$!
4285         local mtime1=`stat -c %Y $DIR1/$tfile`
4286
4287         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4288
4289         kill -USR1 $multipid
4290         wait $multipid || error "multiop close failed"
4291
4292         for (( i=0; i < 2; i++ )) ; do
4293                 local mtime2=`stat -c %Y $DIR1/$tfile`
4294
4295                 [ "$mtime2" = $TEST_39_MTIME ] || \
4296                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4297
4298                 cancel_lru_locks osc
4299                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4300         done
4301 }
4302 run_test 39k "write, utime, close, stat ========================"
4303
4304 # this should be set to future
4305 TEST_39_ATIME=`date -d "1 year" +%s`
4306
4307 test_39l() {
4308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4309         remote_mds_nodsh && skip "remote MDS with nodsh"
4310
4311         local atime_diff=$(do_facet $SINGLEMDS \
4312                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4313         rm -rf $DIR/$tdir
4314         mkdir -p $DIR/$tdir
4315
4316         # test setting directory atime to future
4317         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4318         local atime=$(stat -c %X $DIR/$tdir)
4319         [ "$atime" = $TEST_39_ATIME ] ||
4320                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4321
4322         # test setting directory atime from future to now
4323         local now=$(date +%s)
4324         touch -a -d @$now $DIR/$tdir
4325
4326         atime=$(stat -c %X $DIR/$tdir)
4327         [ "$atime" -eq "$now"  ] ||
4328                 error "atime is not updated from future: $atime, $now"
4329
4330         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4331         sleep 3
4332
4333         # test setting directory atime when now > dir atime + atime_diff
4334         local d1=$(date +%s)
4335         ls $DIR/$tdir
4336         local d2=$(date +%s)
4337         cancel_lru_locks mdc
4338         atime=$(stat -c %X $DIR/$tdir)
4339         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4340                 error "atime is not updated  : $atime, should be $d2"
4341
4342         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4343         sleep 3
4344
4345         # test not setting directory atime when now < dir atime + atime_diff
4346         ls $DIR/$tdir
4347         cancel_lru_locks mdc
4348         atime=$(stat -c %X $DIR/$tdir)
4349         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4350                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4351
4352         do_facet $SINGLEMDS \
4353                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4354 }
4355 run_test 39l "directory atime update ==========================="
4356
4357 test_39m() {
4358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4359
4360         touch $DIR1/$tfile
4361         sleep 2
4362         local far_past_mtime=$(date -d "May 29 1953" +%s)
4363         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4364
4365         touch -m -d @$far_past_mtime $DIR1/$tfile
4366         touch -a -d @$far_past_atime $DIR1/$tfile
4367
4368         for (( i=0; i < 2; i++ )) ; do
4369                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4370                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4371                         error "atime or mtime set incorrectly"
4372
4373                 cancel_lru_locks $OSC
4374                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4375         done
4376 }
4377 run_test 39m "test atime and mtime before 1970"
4378
4379 test_39n() { # LU-3832
4380         remote_mds_nodsh && skip "remote MDS with nodsh"
4381
4382         local atime_diff=$(do_facet $SINGLEMDS \
4383                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4384         local atime0
4385         local atime1
4386         local atime2
4387
4388         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4389
4390         rm -rf $DIR/$tfile
4391         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4392         atime0=$(stat -c %X $DIR/$tfile)
4393
4394         sleep 5
4395         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4396         atime1=$(stat -c %X $DIR/$tfile)
4397
4398         sleep 5
4399         cancel_lru_locks mdc
4400         cancel_lru_locks osc
4401         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4402         atime2=$(stat -c %X $DIR/$tfile)
4403
4404         do_facet $SINGLEMDS \
4405                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4406
4407         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4408         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4409 }
4410 run_test 39n "check that O_NOATIME is honored"
4411
4412 test_39o() {
4413         TESTDIR=$DIR/$tdir/$tfile
4414         [ -e $TESTDIR ] && rm -rf $TESTDIR
4415         mkdir -p $TESTDIR
4416         cd $TESTDIR
4417         links1=2
4418         ls
4419         mkdir a b
4420         ls
4421         links2=$(stat -c %h .)
4422         [ $(($links1 + 2)) != $links2 ] &&
4423                 error "wrong links count $(($links1 + 2)) != $links2"
4424         rmdir b
4425         links3=$(stat -c %h .)
4426         [ $(($links1 + 1)) != $links3 ] &&
4427                 error "wrong links count $links1 != $links3"
4428         return 0
4429 }
4430 run_test 39o "directory cached attributes updated after create"
4431
4432 test_39p() {
4433         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4434
4435         local MDTIDX=1
4436         TESTDIR=$DIR/$tdir/$tdir
4437         [ -e $TESTDIR ] && rm -rf $TESTDIR
4438         test_mkdir -p $TESTDIR
4439         cd $TESTDIR
4440         links1=2
4441         ls
4442         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4443         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4444         ls
4445         links2=$(stat -c %h .)
4446         [ $(($links1 + 2)) != $links2 ] &&
4447                 error "wrong links count $(($links1 + 2)) != $links2"
4448         rmdir remote_dir2
4449         links3=$(stat -c %h .)
4450         [ $(($links1 + 1)) != $links3 ] &&
4451                 error "wrong links count $links1 != $links3"
4452         return 0
4453 }
4454 run_test 39p "remote directory cached attributes updated after create ========"
4455
4456
4457 test_39q() { # LU-8041
4458         local testdir=$DIR/$tdir
4459         mkdir -p $testdir
4460         multiop_bg_pause $testdir D_c || error "multiop failed"
4461         local multipid=$!
4462         cancel_lru_locks mdc
4463         kill -USR1 $multipid
4464         local atime=$(stat -c %X $testdir)
4465         [ "$atime" -ne 0 ] || error "atime is zero"
4466 }
4467 run_test 39q "close won't zero out atime"
4468
4469 test_40() {
4470         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4471         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4472                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4473         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4474                 error "$tfile is not 4096 bytes in size"
4475 }
4476 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4477
4478 test_41() {
4479         # bug 1553
4480         small_write $DIR/f41 18
4481 }
4482 run_test 41 "test small file write + fstat ====================="
4483
4484 count_ost_writes() {
4485         lctl get_param -n ${OSC}.*.stats |
4486                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4487                         END { printf("%0.0f", writes) }'
4488 }
4489
4490 # decent default
4491 WRITEBACK_SAVE=500
4492 DIRTY_RATIO_SAVE=40
4493 MAX_DIRTY_RATIO=50
4494 BG_DIRTY_RATIO_SAVE=10
4495 MAX_BG_DIRTY_RATIO=25
4496
4497 start_writeback() {
4498         trap 0
4499         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4500         # dirty_ratio, dirty_background_ratio
4501         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4502                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4503                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4504                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4505         else
4506                 # if file not here, we are a 2.4 kernel
4507                 kill -CONT `pidof kupdated`
4508         fi
4509 }
4510
4511 stop_writeback() {
4512         # setup the trap first, so someone cannot exit the test at the
4513         # exact wrong time and mess up a machine
4514         trap start_writeback EXIT
4515         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4516         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4517                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4518                 sysctl -w vm.dirty_writeback_centisecs=0
4519                 sysctl -w vm.dirty_writeback_centisecs=0
4520                 # save and increase /proc/sys/vm/dirty_ratio
4521                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4522                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4523                 # save and increase /proc/sys/vm/dirty_background_ratio
4524                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4525                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4526         else
4527                 # if file not here, we are a 2.4 kernel
4528                 kill -STOP `pidof kupdated`
4529         fi
4530 }
4531
4532 # ensure that all stripes have some grant before we test client-side cache
4533 setup_test42() {
4534         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4535                 dd if=/dev/zero of=$i bs=4k count=1
4536                 rm $i
4537         done
4538 }
4539
4540 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4541 # file truncation, and file removal.
4542 test_42a() {
4543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4544
4545         setup_test42
4546         cancel_lru_locks $OSC
4547         stop_writeback
4548         sync; sleep 1; sync # just to be safe
4549         BEFOREWRITES=`count_ost_writes`
4550         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4551         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4552         AFTERWRITES=`count_ost_writes`
4553         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4554                 error "$BEFOREWRITES < $AFTERWRITES"
4555         start_writeback
4556 }
4557 run_test 42a "ensure that we don't flush on close"
4558
4559 test_42b() {
4560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4561
4562         setup_test42
4563         cancel_lru_locks $OSC
4564         stop_writeback
4565         sync
4566         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4567         BEFOREWRITES=$(count_ost_writes)
4568         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4569         AFTERWRITES=$(count_ost_writes)
4570         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4571                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4572         fi
4573         BEFOREWRITES=$(count_ost_writes)
4574         sync || error "sync: $?"
4575         AFTERWRITES=$(count_ost_writes)
4576         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4577                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4578         fi
4579         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4580         start_writeback
4581         return 0
4582 }
4583 run_test 42b "test destroy of file with cached dirty data ======"
4584
4585 # if these tests just want to test the effect of truncation,
4586 # they have to be very careful.  consider:
4587 # - the first open gets a {0,EOF}PR lock
4588 # - the first write conflicts and gets a {0, count-1}PW
4589 # - the rest of the writes are under {count,EOF}PW
4590 # - the open for truncate tries to match a {0,EOF}PR
4591 #   for the filesize and cancels the PWs.
4592 # any number of fixes (don't get {0,EOF} on open, match
4593 # composite locks, do smarter file size management) fix
4594 # this, but for now we want these tests to verify that
4595 # the cancellation with truncate intent works, so we
4596 # start the file with a full-file pw lock to match against
4597 # until the truncate.
4598 trunc_test() {
4599         test=$1
4600         file=$DIR/$test
4601         offset=$2
4602         cancel_lru_locks $OSC
4603         stop_writeback
4604         # prime the file with 0,EOF PW to match
4605         touch $file
4606         $TRUNCATE $file 0
4607         sync; sync
4608         # now the real test..
4609         dd if=/dev/zero of=$file bs=1024 count=100
4610         BEFOREWRITES=`count_ost_writes`
4611         $TRUNCATE $file $offset
4612         cancel_lru_locks $OSC
4613         AFTERWRITES=`count_ost_writes`
4614         start_writeback
4615 }
4616
4617 test_42c() {
4618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4619
4620         trunc_test 42c 1024
4621         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4622                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4623         rm $file
4624 }
4625 run_test 42c "test partial truncate of file with cached dirty data"
4626
4627 test_42d() {
4628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4629
4630         trunc_test 42d 0
4631         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4632                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4633         rm $file
4634 }
4635 run_test 42d "test complete truncate of file with cached dirty data"
4636
4637 test_42e() { # bug22074
4638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4639
4640         local TDIR=$DIR/${tdir}e
4641         local pages=16 # hardcoded 16 pages, don't change it.
4642         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4643         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4644         local max_dirty_mb
4645         local warmup_files
4646
4647         test_mkdir $DIR/${tdir}e
4648         $LFS setstripe -c 1 $TDIR
4649         createmany -o $TDIR/f $files
4650
4651         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4652
4653         # we assume that with $OSTCOUNT files, at least one of them will
4654         # be allocated on OST0.
4655         warmup_files=$((OSTCOUNT * max_dirty_mb))
4656         createmany -o $TDIR/w $warmup_files
4657
4658         # write a large amount of data into one file and sync, to get good
4659         # avail_grant number from OST.
4660         for ((i=0; i<$warmup_files; i++)); do
4661                 idx=$($LFS getstripe -i $TDIR/w$i)
4662                 [ $idx -ne 0 ] && continue
4663                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4664                 break
4665         done
4666         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4667         sync
4668         $LCTL get_param $proc_osc0/cur_dirty_bytes
4669         $LCTL get_param $proc_osc0/cur_grant_bytes
4670
4671         # create as much dirty pages as we can while not to trigger the actual
4672         # RPCs directly. but depends on the env, VFS may trigger flush during this
4673         # period, hopefully we are good.
4674         for ((i=0; i<$warmup_files; i++)); do
4675                 idx=$($LFS getstripe -i $TDIR/w$i)
4676                 [ $idx -ne 0 ] && continue
4677                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4678         done
4679         $LCTL get_param $proc_osc0/cur_dirty_bytes
4680         $LCTL get_param $proc_osc0/cur_grant_bytes
4681
4682         # perform the real test
4683         $LCTL set_param $proc_osc0/rpc_stats 0
4684         for ((;i<$files; i++)); do
4685                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4686                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4687         done
4688         sync
4689         $LCTL get_param $proc_osc0/rpc_stats
4690
4691         local percent=0
4692         local have_ppr=false
4693         $LCTL get_param $proc_osc0/rpc_stats |
4694                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4695                         # skip lines until we are at the RPC histogram data
4696                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4697                         $have_ppr || continue
4698
4699                         # we only want the percent stat for < 16 pages
4700                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4701
4702                         percent=$((percent + WPCT))
4703                         if [[ $percent -gt 15 ]]; then
4704                                 error "less than 16-pages write RPCs" \
4705                                       "$percent% > 15%"
4706                                 break
4707                         fi
4708                 done
4709         rm -rf $TDIR
4710 }
4711 run_test 42e "verify sub-RPC writes are not done synchronously"
4712
4713 test_43A() { # was test_43
4714         test_mkdir $DIR/$tdir
4715         cp -p /bin/ls $DIR/$tdir/$tfile
4716         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4717         pid=$!
4718         # give multiop a chance to open
4719         sleep 1
4720
4721         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4722         kill -USR1 $pid
4723 }
4724 run_test 43A "execution of file opened for write should return -ETXTBSY"
4725
4726 test_43a() {
4727         test_mkdir $DIR/$tdir
4728         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4729         $DIR/$tdir/sleep 60 &
4730         SLEEP_PID=$!
4731         # Make sure exec of $tdir/sleep wins race with truncate
4732         sleep 1
4733         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4734         kill $SLEEP_PID
4735 }
4736 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4737
4738 test_43b() {
4739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4740
4741         test_mkdir $DIR/$tdir
4742         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4743         $DIR/$tdir/sleep 60 &
4744         SLEEP_PID=$!
4745         # Make sure exec of $tdir/sleep wins race with truncate
4746         sleep 1
4747         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4748         kill $SLEEP_PID
4749 }
4750 run_test 43b "truncate of file being executed should return -ETXTBSY"
4751
4752 test_43c() {
4753         local testdir="$DIR/$tdir"
4754         test_mkdir $testdir
4755         cp $SHELL $testdir/
4756         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4757                 ( cd $testdir && md5sum -c )
4758 }
4759 run_test 43c "md5sum of copy into lustre"
4760
4761 test_44A() { # was test_44
4762         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4763
4764         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4765         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4766 }
4767 run_test 44A "zero length read from a sparse stripe"
4768
4769 test_44a() {
4770         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4771                 awk '{ print $2 }')
4772         [ -z "$nstripe" ] && skip "can't get stripe info"
4773         [[ $nstripe -gt $OSTCOUNT ]] &&
4774                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4775
4776         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4777                 awk '{ print $2 }')
4778         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4779                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4780                         awk '{ print $2 }')
4781         fi
4782
4783         OFFSETS="0 $((stride/2)) $((stride-1))"
4784         for offset in $OFFSETS; do
4785                 for i in $(seq 0 $((nstripe-1))); do
4786                         local GLOBALOFFSETS=""
4787                         # size in Bytes
4788                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4789                         local myfn=$DIR/d44a-$size
4790                         echo "--------writing $myfn at $size"
4791                         ll_sparseness_write $myfn $size ||
4792                                 error "ll_sparseness_write"
4793                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4794                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4795                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4796
4797                         for j in $(seq 0 $((nstripe-1))); do
4798                                 # size in Bytes
4799                                 size=$((((j + $nstripe )*$stride + $offset)))
4800                                 ll_sparseness_write $myfn $size ||
4801                                         error "ll_sparseness_write"
4802                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4803                         done
4804                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4805                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4806                         rm -f $myfn
4807                 done
4808         done
4809 }
4810 run_test 44a "test sparse pwrite ==============================="
4811
4812 dirty_osc_total() {
4813         tot=0
4814         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4815                 tot=$(($tot + $d))
4816         done
4817         echo $tot
4818 }
4819 do_dirty_record() {
4820         before=`dirty_osc_total`
4821         echo executing "\"$*\""
4822         eval $*
4823         after=`dirty_osc_total`
4824         echo before $before, after $after
4825 }
4826 test_45() {
4827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4828
4829         f="$DIR/f45"
4830         # Obtain grants from OST if it supports it
4831         echo blah > ${f}_grant
4832         stop_writeback
4833         sync
4834         do_dirty_record "echo blah > $f"
4835         [[ $before -eq $after ]] && error "write wasn't cached"
4836         do_dirty_record "> $f"
4837         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4838         do_dirty_record "echo blah > $f"
4839         [[ $before -eq $after ]] && error "write wasn't cached"
4840         do_dirty_record "sync"
4841         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4842         do_dirty_record "echo blah > $f"
4843         [[ $before -eq $after ]] && error "write wasn't cached"
4844         do_dirty_record "cancel_lru_locks osc"
4845         [[ $before -gt $after ]] ||
4846                 error "lock cancellation didn't lower dirty count"
4847         start_writeback
4848 }
4849 run_test 45 "osc io page accounting ============================"
4850
4851 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4852 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4853 # objects offset and an assert hit when an rpc was built with 1023's mapped
4854 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4855 test_46() {
4856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4857
4858         f="$DIR/f46"
4859         stop_writeback
4860         sync
4861         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4862         sync
4863         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4864         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4865         sync
4866         start_writeback
4867 }
4868 run_test 46 "dirtying a previously written page ================"
4869
4870 # test_47 is removed "Device nodes check" is moved to test_28
4871
4872 test_48a() { # bug 2399
4873         [ "$mds1_FSTYPE" = "zfs" ] &&
4874         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4875                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4876
4877         test_mkdir $DIR/$tdir
4878         cd $DIR/$tdir
4879         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4880         test_mkdir $DIR/$tdir
4881         touch foo || error "'touch foo' failed after recreating cwd"
4882         test_mkdir bar
4883         touch .foo || error "'touch .foo' failed after recreating cwd"
4884         test_mkdir .bar
4885         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4886         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4887         cd . || error "'cd .' failed after recreating cwd"
4888         mkdir . && error "'mkdir .' worked after recreating cwd"
4889         rmdir . && error "'rmdir .' worked after recreating cwd"
4890         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4891         cd .. || error "'cd ..' failed after recreating cwd"
4892 }
4893 run_test 48a "Access renamed working dir (should return errors)="
4894
4895 test_48b() { # bug 2399
4896         rm -rf $DIR/$tdir
4897         test_mkdir $DIR/$tdir
4898         cd $DIR/$tdir
4899         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4900         touch foo && error "'touch foo' worked after removing cwd"
4901         mkdir foo && error "'mkdir foo' worked after removing cwd"
4902         touch .foo && error "'touch .foo' worked after removing cwd"
4903         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4904         ls . > /dev/null && error "'ls .' worked after removing cwd"
4905         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4906         mkdir . && error "'mkdir .' worked after removing cwd"
4907         rmdir . && error "'rmdir .' worked after removing cwd"
4908         ln -s . foo && error "'ln -s .' worked after removing cwd"
4909         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4910 }
4911 run_test 48b "Access removed working dir (should return errors)="
4912
4913 test_48c() { # bug 2350
4914         #lctl set_param debug=-1
4915         #set -vx
4916         rm -rf $DIR/$tdir
4917         test_mkdir -p $DIR/$tdir/dir
4918         cd $DIR/$tdir/dir
4919         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4920         $TRACE touch foo && error "touch foo worked after removing cwd"
4921         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4922         touch .foo && error "touch .foo worked after removing cwd"
4923         mkdir .foo && error "mkdir .foo worked after removing cwd"
4924         $TRACE ls . && error "'ls .' worked after removing cwd"
4925         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4926         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4927         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4928         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4929         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4930 }
4931 run_test 48c "Access removed working subdir (should return errors)"
4932
4933 test_48d() { # bug 2350
4934         #lctl set_param debug=-1
4935         #set -vx
4936         rm -rf $DIR/$tdir
4937         test_mkdir -p $DIR/$tdir/dir
4938         cd $DIR/$tdir/dir
4939         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4940         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4941         $TRACE touch foo && error "'touch foo' worked after removing parent"
4942         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4943         touch .foo && error "'touch .foo' worked after removing parent"
4944         mkdir .foo && error "mkdir .foo worked after removing parent"
4945         $TRACE ls . && error "'ls .' worked after removing parent"
4946         $TRACE ls .. && error "'ls ..' worked after removing parent"
4947         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4948         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4949         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4950         true
4951 }
4952 run_test 48d "Access removed parent subdir (should return errors)"
4953
4954 test_48e() { # bug 4134
4955         #lctl set_param debug=-1
4956         #set -vx
4957         rm -rf $DIR/$tdir
4958         test_mkdir -p $DIR/$tdir/dir
4959         cd $DIR/$tdir/dir
4960         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4961         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4962         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4963         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4964         # On a buggy kernel addition of "touch foo" after cd .. will
4965         # produce kernel oops in lookup_hash_it
4966         touch ../foo && error "'cd ..' worked after recreate parent"
4967         cd $DIR
4968         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4969 }
4970 run_test 48e "Access to recreated parent subdir (should return errors)"
4971
4972 test_49() { # LU-1030
4973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4974         remote_ost_nodsh && skip "remote OST with nodsh"
4975
4976         # get ost1 size - lustre-OST0000
4977         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4978                 awk '{ print $4 }')
4979         # write 800M at maximum
4980         [[ $ost1_size -lt 2 ]] && ost1_size=2
4981         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4982
4983         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4984         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4985         local dd_pid=$!
4986
4987         # change max_pages_per_rpc while writing the file
4988         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4989         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4990         # loop until dd process exits
4991         while ps ax -opid | grep -wq $dd_pid; do
4992                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4993                 sleep $((RANDOM % 5 + 1))
4994         done
4995         # restore original max_pages_per_rpc
4996         $LCTL set_param $osc1_mppc=$orig_mppc
4997         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4998 }
4999 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5000
5001 test_50() {
5002         # bug 1485
5003         test_mkdir $DIR/$tdir
5004         cd $DIR/$tdir
5005         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5006 }
5007 run_test 50 "special situations: /proc symlinks  ==============="
5008
5009 test_51a() {    # was test_51
5010         # bug 1516 - create an empty entry right after ".." then split dir
5011         test_mkdir -c1 $DIR/$tdir
5012         touch $DIR/$tdir/foo
5013         $MCREATE $DIR/$tdir/bar
5014         rm $DIR/$tdir/foo
5015         createmany -m $DIR/$tdir/longfile 201
5016         FNUM=202
5017         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5018                 $MCREATE $DIR/$tdir/longfile$FNUM
5019                 FNUM=$(($FNUM + 1))
5020                 echo -n "+"
5021         done
5022         echo
5023         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5024 }
5025 run_test 51a "special situations: split htree with empty entry =="
5026
5027 cleanup_print_lfs_df () {
5028         trap 0
5029         $LFS df
5030         $LFS df -i
5031 }
5032
5033 test_51b() {
5034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5035
5036         local dir=$DIR/$tdir
5037         local nrdirs=$((65536 + 100))
5038
5039         # cleanup the directory
5040         rm -fr $dir
5041
5042         test_mkdir -c1 $dir
5043
5044         $LFS df
5045         $LFS df -i
5046         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5047         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5048         [[ $numfree -lt $nrdirs ]] &&
5049                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5050
5051         # need to check free space for the directories as well
5052         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5053         numfree=$(( blkfree / $(fs_inode_ksize) ))
5054         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5055
5056         trap cleanup_print_lfs_df EXIT
5057
5058         # create files
5059         createmany -d $dir/d $nrdirs || {
5060                 unlinkmany $dir/d $nrdirs
5061                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5062         }
5063
5064         # really created :
5065         nrdirs=$(ls -U $dir | wc -l)
5066
5067         # unlink all but 100 subdirectories, then check it still works
5068         local left=100
5069         local delete=$((nrdirs - left))
5070
5071         $LFS df
5072         $LFS df -i
5073
5074         # for ldiskfs the nlink count should be 1, but this is OSD specific
5075         # and so this is listed for informational purposes only
5076         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5077         unlinkmany -d $dir/d $delete ||
5078                 error "unlink of first $delete subdirs failed"
5079
5080         echo "nlink between: $(stat -c %h $dir)"
5081         local found=$(ls -U $dir | wc -l)
5082         [ $found -ne $left ] &&
5083                 error "can't find subdirs: found only $found, expected $left"
5084
5085         unlinkmany -d $dir/d $delete $left ||
5086                 error "unlink of second $left subdirs failed"
5087         # regardless of whether the backing filesystem tracks nlink accurately
5088         # or not, the nlink count shouldn't be more than "." and ".." here
5089         local after=$(stat -c %h $dir)
5090         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5091                 echo "nlink after: $after"
5092
5093         cleanup_print_lfs_df
5094 }
5095 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5096
5097 test_51d() {
5098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5099         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5100
5101         test_mkdir $DIR/$tdir
5102         createmany -o $DIR/$tdir/t- 1000
5103         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5104         for N in $(seq 0 $((OSTCOUNT - 1))); do
5105                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5106                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5107                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5108                         '($1 == '$N') { objs += 1 } \
5109                         END { printf("%0.0f", objs) }')
5110                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5111         done
5112         unlinkmany $DIR/$tdir/t- 1000
5113
5114         NLAST=0
5115         for N in $(seq 1 $((OSTCOUNT - 1))); do
5116                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5117                         error "OST $N has less objects vs OST $NLAST" \
5118                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5119                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5120                         error "OST $N has less objects vs OST $NLAST" \
5121                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5122
5123                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5124                         error "OST $N has less #0 objects vs OST $NLAST" \
5125                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5126                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5127                         error "OST $N has less #0 objects vs OST $NLAST" \
5128                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5129                 NLAST=$N
5130         done
5131         rm -f $TMP/$tfile
5132 }
5133 run_test 51d "check object distribution"
5134
5135 test_51e() {
5136         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5137                 skip_env "ldiskfs only test"
5138         fi
5139
5140         test_mkdir -c1 $DIR/$tdir
5141         test_mkdir -c1 $DIR/$tdir/d0
5142
5143         touch $DIR/$tdir/d0/foo
5144         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5145                 error "file exceed 65000 nlink limit!"
5146         unlinkmany $DIR/$tdir/d0/f- 65001
5147         return 0
5148 }
5149 run_test 51e "check file nlink limit"
5150
5151 test_51f() {
5152         test_mkdir $DIR/$tdir
5153
5154         local max=100000
5155         local ulimit_old=$(ulimit -n)
5156         local spare=20 # number of spare fd's for scripts/libraries, etc.
5157         local mdt=$($LFS getstripe -m $DIR/$tdir)
5158         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5159
5160         echo "MDT$mdt numfree=$numfree, max=$max"
5161         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5162         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5163                 while ! ulimit -n $((numfree + spare)); do
5164                         numfree=$((numfree * 3 / 4))
5165                 done
5166                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5167         else
5168                 echo "left ulimit at $ulimit_old"
5169         fi
5170
5171         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5172                 unlinkmany $DIR/$tdir/f $numfree
5173                 error "create+open $numfree files in $DIR/$tdir failed"
5174         }
5175         ulimit -n $ulimit_old
5176
5177         # if createmany exits at 120s there will be fewer than $numfree files
5178         unlinkmany $DIR/$tdir/f $numfree || true
5179 }
5180 run_test 51f "check many open files limit"
5181
5182 test_52a() {
5183         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5184         test_mkdir $DIR/$tdir
5185         touch $DIR/$tdir/foo
5186         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5187         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5188         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5189         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5190         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5191                                         error "link worked"
5192         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5193         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5194         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5195                                                      error "lsattr"
5196         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5197         cp -r $DIR/$tdir $TMP/
5198         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5199 }
5200 run_test 52a "append-only flag test (should return errors)"
5201
5202 test_52b() {
5203         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5204         test_mkdir $DIR/$tdir
5205         touch $DIR/$tdir/foo
5206         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5207         cat test > $DIR/$tdir/foo && error "cat test worked"
5208         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5209         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5210         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5211                                         error "link worked"
5212         echo foo >> $DIR/$tdir/foo && error "echo worked"
5213         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5214         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5215         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5216         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5217                                                         error "lsattr"
5218         chattr -i $DIR/$tdir/foo || error "chattr failed"
5219
5220         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5221 }
5222 run_test 52b "immutable flag test (should return errors) ======="
5223
5224 test_53() {
5225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5226         remote_mds_nodsh && skip "remote MDS with nodsh"
5227         remote_ost_nodsh && skip "remote OST with nodsh"
5228
5229         local param
5230         local param_seq
5231         local ostname
5232         local mds_last
5233         local mds_last_seq
5234         local ost_last
5235         local ost_last_seq
5236         local ost_last_id
5237         local ostnum
5238         local node
5239         local found=false
5240         local support_last_seq=true
5241
5242         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5243                 support_last_seq=false
5244
5245         # only test MDT0000
5246         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5247         local value
5248         for value in $(do_facet $SINGLEMDS \
5249                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5250                 param=$(echo ${value[0]} | cut -d "=" -f1)
5251                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5252
5253                 if $support_last_seq; then
5254                         param_seq=$(echo $param |
5255                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5256                         mds_last_seq=$(do_facet $SINGLEMDS \
5257                                        $LCTL get_param -n $param_seq)
5258                 fi
5259                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5260
5261                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5262                 node=$(facet_active_host ost$((ostnum+1)))
5263                 param="obdfilter.$ostname.last_id"
5264                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5265                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5266                         ost_last_id=$ost_last
5267
5268                         if $support_last_seq; then
5269                                 ost_last_id=$(echo $ost_last |
5270                                               awk -F':' '{print $2}' |
5271                                               sed -e "s/^0x//g")
5272                                 ost_last_seq=$(echo $ost_last |
5273                                                awk -F':' '{print $1}')
5274                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5275                         fi
5276
5277                         if [[ $ost_last_id != $mds_last ]]; then
5278                                 error "$ost_last_id != $mds_last"
5279                         else
5280                                 found=true
5281                                 break
5282                         fi
5283                 done
5284         done
5285         $found || error "can not match last_seq/last_id for $mdtosc"
5286         return 0
5287 }
5288 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5289
5290 test_54a() {
5291         perl -MSocket -e ';' || skip "no Socket perl module installed"
5292
5293         $SOCKETSERVER $DIR/socket ||
5294                 error "$SOCKETSERVER $DIR/socket failed: $?"
5295         $SOCKETCLIENT $DIR/socket ||
5296                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5297         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5298 }
5299 run_test 54a "unix domain socket test =========================="
5300
5301 test_54b() {
5302         f="$DIR/f54b"
5303         mknod $f c 1 3
5304         chmod 0666 $f
5305         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5306 }
5307 run_test 54b "char device works in lustre ======================"
5308
5309 find_loop_dev() {
5310         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5311         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5312         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5313
5314         for i in $(seq 3 7); do
5315                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5316                 LOOPDEV=$LOOPBASE$i
5317                 LOOPNUM=$i
5318                 break
5319         done
5320 }
5321
5322 cleanup_54c() {
5323         local rc=0
5324         loopdev="$DIR/loop54c"
5325
5326         trap 0
5327         $UMOUNT $DIR/$tdir || rc=$?
5328         losetup -d $loopdev || true
5329         losetup -d $LOOPDEV || true
5330         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5331         return $rc
5332 }
5333
5334 test_54c() {
5335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5336
5337         loopdev="$DIR/loop54c"
5338
5339         find_loop_dev
5340         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5341         trap cleanup_54c EXIT
5342         mknod $loopdev b 7 $LOOPNUM
5343         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5344         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5345         losetup $loopdev $DIR/$tfile ||
5346                 error "can't set up $loopdev for $DIR/$tfile"
5347         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5348         test_mkdir $DIR/$tdir
5349         mount -t ext2 $loopdev $DIR/$tdir ||
5350                 error "error mounting $loopdev on $DIR/$tdir"
5351         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5352                 error "dd write"
5353         df $DIR/$tdir
5354         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5355                 error "dd read"
5356         cleanup_54c
5357 }
5358 run_test 54c "block device works in lustre ====================="
5359
5360 test_54d() {
5361         f="$DIR/f54d"
5362         string="aaaaaa"
5363         mknod $f p
5364         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5365 }
5366 run_test 54d "fifo device works in lustre ======================"
5367
5368 test_54e() {
5369         f="$DIR/f54e"
5370         string="aaaaaa"
5371         cp -aL /dev/console $f
5372         echo $string > $f || error "echo $string to $f failed"
5373 }
5374 run_test 54e "console/tty device works in lustre ======================"
5375
5376 test_56a() {
5377         local numfiles=3
5378         local dir=$DIR/$tdir
5379
5380         rm -rf $dir
5381         test_mkdir -p $dir/dir
5382         for i in $(seq $numfiles); do
5383                 touch $dir/file$i
5384                 touch $dir/dir/file$i
5385         done
5386
5387         local numcomp=$($LFS getstripe --component-count $dir)
5388
5389         [[ $numcomp == 0 ]] && numcomp=1
5390
5391         # test lfs getstripe with --recursive
5392         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5393
5394         [[ $filenum -eq $((numfiles * 2)) ]] ||
5395                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5396         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5397         [[ $filenum -eq $numfiles ]] ||
5398                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5399         echo "$LFS getstripe showed obdidx or l_ost_idx"
5400
5401         # test lfs getstripe with file instead of dir
5402         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5403         [[ $filenum -eq 1 ]] ||
5404                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5405         echo "$LFS getstripe file1 passed"
5406
5407         #test lfs getstripe with --verbose
5408         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5409         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5410                 error "$LFS getstripe --verbose $dir: "\
5411                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5412         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5413                 error "$LFS getstripe $dir: showed lmm_magic"
5414
5415         #test lfs getstripe with -v prints lmm_fid
5416         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5417         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5418                 error "$LFS getstripe -v $dir: "\
5419                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5420         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5421                 error "$LFS getstripe $dir: showed lmm_fid by default"
5422         echo "$LFS getstripe --verbose passed"
5423
5424         #check for FID information
5425         local fid1=$($LFS getstripe --fid $dir/file1)
5426         local fid2=$($LFS getstripe --verbose $dir/file1 |
5427                      awk '/lmm_fid: / { print $2; exit; }')
5428         local fid3=$($LFS path2fid $dir/file1)
5429
5430         [ "$fid1" != "$fid2" ] &&
5431                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5432         [ "$fid1" != "$fid3" ] &&
5433                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5434         echo "$LFS getstripe --fid passed"
5435
5436         #test lfs getstripe with --obd
5437         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5438                 error "$LFS getstripe --obd wrong_uuid: should return error"
5439
5440         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5441
5442         local ostidx=1
5443         local obduuid=$(ostuuid_from_index $ostidx)
5444         local found=$($LFS getstripe -r --obd $obduuid $dir |
5445                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5446
5447         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5448         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5449                 ((filenum--))
5450         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5451                 ((filenum--))
5452
5453         [[ $found -eq $filenum ]] ||
5454                 error "$LFS getstripe --obd: found $found expect $filenum"
5455         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5456                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5457                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5458                 error "$LFS getstripe --obd: should not show file on other obd"
5459         echo "$LFS getstripe --obd passed"
5460 }
5461 run_test 56a "check $LFS getstripe"
5462
5463 test_56b() {
5464         local dir=$DIR/$tdir
5465         local numdirs=3
5466
5467         test_mkdir $dir
5468         for i in $(seq $numdirs); do
5469                 test_mkdir $dir/dir$i
5470         done
5471
5472         # test lfs getdirstripe default mode is non-recursion, which is
5473         # different from lfs getstripe
5474         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5475
5476         [[ $dircnt -eq 1 ]] ||
5477                 error "$LFS getdirstripe: found $dircnt, not 1"
5478         dircnt=$($LFS getdirstripe --recursive $dir |
5479                 grep -c lmv_stripe_count)
5480         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5481                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5482 }
5483 run_test 56b "check $LFS getdirstripe"
5484
5485 test_56c() {
5486         remote_ost_nodsh && skip "remote OST with nodsh"
5487
5488         local ost_idx=0
5489         local ost_name=$(ostname_from_index $ost_idx)
5490         local old_status=$(ost_dev_status $ost_idx)
5491
5492         [[ -z "$old_status" ]] ||
5493                 skip_env "OST $ost_name is in $old_status status"
5494
5495         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5496         sleep_maxage
5497
5498         local new_status=$(ost_dev_status $ost_idx)
5499
5500         [[ "$new_status" = "D" ]] ||
5501                 error "OST $ost_name is in status of '$new_status', not 'D'"
5502
5503         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5504         sleep_maxage
5505
5506         new_status=$(ost_dev_status $ost_idx)
5507         [[ -z "$new_status" ]] ||
5508                 error "OST $ost_name is in status of '$new_status', not ''"
5509 }
5510 run_test 56c "check 'lfs df' showing device status"
5511
5512 NUMFILES=3
5513 NUMDIRS=3
5514 setup_56() {
5515         local local_tdir="$1"
5516         local local_numfiles="$2"
5517         local local_numdirs="$3"
5518         local dir_params="$4"
5519         local dir_stripe_params="$5"
5520
5521         if [ ! -d "$local_tdir" ] ; then
5522                 test_mkdir -p $dir_stripe_params $local_tdir
5523                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5524                 for i in $(seq $local_numfiles) ; do
5525                         touch $local_tdir/file$i
5526                 done
5527                 for i in $(seq $local_numdirs) ; do
5528                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5529                         for j in $(seq $local_numfiles) ; do
5530                                 touch $local_tdir/dir$i/file$j
5531                         done
5532                 done
5533         fi
5534 }
5535
5536 setup_56_special() {
5537         local local_tdir=$1
5538         local local_numfiles=$2
5539         local local_numdirs=$3
5540
5541         setup_56 $local_tdir $local_numfiles $local_numdirs
5542
5543         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5544                 for i in $(seq $local_numfiles) ; do
5545                         mknod $local_tdir/loop${i}b b 7 $i
5546                         mknod $local_tdir/null${i}c c 1 3
5547                         ln -s $local_tdir/file1 $local_tdir/link${i}
5548                 done
5549                 for i in $(seq $local_numdirs) ; do
5550                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5551                         mknod $local_tdir/dir$i/null${i}c c 1 3
5552                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5553                 done
5554         fi
5555 }
5556
5557 test_56g() {
5558         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5559         local expected=$(($NUMDIRS + 2))
5560
5561         setup_56 $dir $NUMFILES $NUMDIRS
5562
5563         # test lfs find with -name
5564         for i in $(seq $NUMFILES) ; do
5565                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5566
5567                 [ $nums -eq $expected ] ||
5568                         error "lfs find -name '*$i' $dir wrong: "\
5569                               "found $nums, expected $expected"
5570         done
5571 }
5572 run_test 56g "check lfs find -name"
5573
5574 test_56h() {
5575         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5576         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5577
5578         setup_56 $dir $NUMFILES $NUMDIRS
5579
5580         # test lfs find with ! -name
5581         for i in $(seq $NUMFILES) ; do
5582                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5583
5584                 [ $nums -eq $expected ] ||
5585                         error "lfs find ! -name '*$i' $dir wrong: "\
5586                               "found $nums, expected $expected"
5587         done
5588 }
5589 run_test 56h "check lfs find ! -name"
5590
5591 test_56i() {
5592         local dir=$DIR/$tdir
5593
5594         test_mkdir $dir
5595
5596         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5597         local out=$($cmd)
5598
5599         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5600 }
5601 run_test 56i "check 'lfs find -ost UUID' skips directories"
5602
5603 test_56j() {
5604         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5605
5606         setup_56_special $dir $NUMFILES $NUMDIRS
5607
5608         local expected=$((NUMDIRS + 1))
5609         local cmd="$LFS find -type d $dir"
5610         local nums=$($cmd | wc -l)
5611
5612         [ $nums -eq $expected ] ||
5613                 error "'$cmd' wrong: found $nums, expected $expected"
5614 }
5615 run_test 56j "check lfs find -type d"
5616
5617 test_56k() {
5618         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5619
5620         setup_56_special $dir $NUMFILES $NUMDIRS
5621
5622         local expected=$(((NUMDIRS + 1) * NUMFILES))
5623         local cmd="$LFS find -type f $dir"
5624         local nums=$($cmd | wc -l)
5625
5626         [ $nums -eq $expected ] ||
5627                 error "'$cmd' wrong: found $nums, expected $expected"
5628 }
5629 run_test 56k "check lfs find -type f"
5630
5631 test_56l() {
5632         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5633
5634         setup_56_special $dir $NUMFILES $NUMDIRS
5635
5636         local expected=$((NUMDIRS + NUMFILES))
5637         local cmd="$LFS find -type b $dir"
5638         local nums=$($cmd | wc -l)
5639
5640         [ $nums -eq $expected ] ||
5641                 error "'$cmd' wrong: found $nums, expected $expected"
5642 }
5643 run_test 56l "check lfs find -type b"
5644
5645 test_56m() {
5646         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5647
5648         setup_56_special $dir $NUMFILES $NUMDIRS
5649
5650         local expected=$((NUMDIRS + NUMFILES))
5651         local cmd="$LFS find -type c $dir"
5652         local nums=$($cmd | wc -l)
5653         [ $nums -eq $expected ] ||
5654                 error "'$cmd' wrong: found $nums, expected $expected"
5655 }
5656 run_test 56m "check lfs find -type c"
5657
5658 test_56n() {
5659         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5660         setup_56_special $dir $NUMFILES $NUMDIRS
5661
5662         local expected=$((NUMDIRS + NUMFILES))
5663         local cmd="$LFS find -type l $dir"
5664         local nums=$($cmd | wc -l)
5665
5666         [ $nums -eq $expected ] ||
5667                 error "'$cmd' wrong: found $nums, expected $expected"
5668 }
5669 run_test 56n "check lfs find -type l"
5670
5671 test_56o() {
5672         local dir=$DIR/$tdir
5673
5674         setup_56 $dir $NUMFILES $NUMDIRS
5675         utime $dir/file1 > /dev/null || error "utime (1)"
5676         utime $dir/file2 > /dev/null || error "utime (2)"
5677         utime $dir/dir1 > /dev/null || error "utime (3)"
5678         utime $dir/dir2 > /dev/null || error "utime (4)"
5679         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5680         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5681
5682         local expected=4
5683         local nums=$($LFS find -mtime +0 $dir | wc -l)
5684
5685         [ $nums -eq $expected ] ||
5686                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5687
5688         expected=12
5689         cmd="$LFS find -mtime 0 $dir"
5690         nums=$($cmd | wc -l)
5691         [ $nums -eq $expected ] ||
5692                 error "'$cmd' wrong: found $nums, expected $expected"
5693 }
5694 run_test 56o "check lfs find -mtime for old files"
5695
5696 test_56ob() {
5697         local dir=$DIR/$tdir
5698         local expected=1
5699         local count=0
5700
5701         # just to make sure there is something that won't be found
5702         test_mkdir $dir
5703         touch $dir/$tfile.now
5704
5705         for age in year week day hour min; do
5706                 count=$((count + 1))
5707
5708                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5709                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5710                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5711
5712                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5713                 local nums=$($cmd | wc -l)
5714                 [ $nums -eq $expected ] ||
5715                         error "'$cmd' wrong: found $nums, expected $expected"
5716
5717                 cmd="$LFS find $dir -atime $count${age:0:1}"
5718                 nums=$($cmd | wc -l)
5719                 [ $nums -eq $expected ] ||
5720                         error "'$cmd' wrong: found $nums, expected $expected"
5721         done
5722
5723         sleep 2
5724         cmd="$LFS find $dir -ctime +1s -type f"
5725         nums=$($cmd | wc -l)
5726         (( $nums == $count * 2 + 1)) ||
5727                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5728 }
5729 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5730
5731 test_56p() {
5732         [ $RUNAS_ID -eq $UID ] &&
5733                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5734
5735         local dir=$DIR/$tdir
5736
5737         setup_56 $dir $NUMFILES $NUMDIRS
5738         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5739
5740         local expected=$NUMFILES
5741         local cmd="$LFS find -uid $RUNAS_ID $dir"
5742         local nums=$($cmd | wc -l)
5743
5744         [ $nums -eq $expected ] ||
5745                 error "'$cmd' wrong: found $nums, expected $expected"
5746
5747         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5748         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5749         nums=$($cmd | wc -l)
5750         [ $nums -eq $expected ] ||
5751                 error "'$cmd' wrong: found $nums, expected $expected"
5752 }
5753 run_test 56p "check lfs find -uid and ! -uid"
5754
5755 test_56q() {
5756         [ $RUNAS_ID -eq $UID ] &&
5757                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5758
5759         local dir=$DIR/$tdir
5760
5761         setup_56 $dir $NUMFILES $NUMDIRS
5762         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5763
5764         local expected=$NUMFILES
5765         local cmd="$LFS find -gid $RUNAS_GID $dir"
5766         local nums=$($cmd | wc -l)
5767
5768         [ $nums -eq $expected ] ||
5769                 error "'$cmd' wrong: found $nums, expected $expected"
5770
5771         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5772         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5773         nums=$($cmd | wc -l)
5774         [ $nums -eq $expected ] ||
5775                 error "'$cmd' wrong: found $nums, expected $expected"
5776 }
5777 run_test 56q "check lfs find -gid and ! -gid"
5778
5779 test_56r() {
5780         local dir=$DIR/$tdir
5781
5782         setup_56 $dir $NUMFILES $NUMDIRS
5783
5784         local expected=12
5785         local cmd="$LFS find -size 0 -type f -lazy $dir"
5786         local nums=$($cmd | wc -l)
5787
5788         [ $nums -eq $expected ] ||
5789                 error "'$cmd' wrong: found $nums, expected $expected"
5790         cmd="$LFS find -size 0 -type f $dir"
5791         nums=$($cmd | wc -l)
5792         [ $nums -eq $expected ] ||
5793                 error "'$cmd' wrong: found $nums, expected $expected"
5794
5795         expected=0
5796         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5797         nums=$($cmd | wc -l)
5798         [ $nums -eq $expected ] ||
5799                 error "'$cmd' wrong: found $nums, expected $expected"
5800         cmd="$LFS find ! -size 0 -type f $dir"
5801         nums=$($cmd | wc -l)
5802         [ $nums -eq $expected ] ||
5803                 error "'$cmd' wrong: found $nums, expected $expected"
5804
5805         echo "test" > $dir/$tfile
5806         echo "test2" > $dir/$tfile.2 && sync
5807         expected=1
5808         cmd="$LFS find -size 5 -type f -lazy $dir"
5809         nums=$($cmd | wc -l)
5810         [ $nums -eq $expected ] ||
5811                 error "'$cmd' wrong: found $nums, expected $expected"
5812         cmd="$LFS find -size 5 -type f $dir"
5813         nums=$($cmd | wc -l)
5814         [ $nums -eq $expected ] ||
5815                 error "'$cmd' wrong: found $nums, expected $expected"
5816
5817         expected=1
5818         cmd="$LFS find -size +5 -type f -lazy $dir"
5819         nums=$($cmd | wc -l)
5820         [ $nums -eq $expected ] ||
5821                 error "'$cmd' wrong: found $nums, expected $expected"
5822         cmd="$LFS find -size +5 -type f $dir"
5823         nums=$($cmd | wc -l)
5824         [ $nums -eq $expected ] ||
5825                 error "'$cmd' wrong: found $nums, expected $expected"
5826
5827         expected=2
5828         cmd="$LFS find -size +0 -type f -lazy $dir"
5829         nums=$($cmd | wc -l)
5830         [ $nums -eq $expected ] ||
5831                 error "'$cmd' wrong: found $nums, expected $expected"
5832         cmd="$LFS find -size +0 -type f $dir"
5833         nums=$($cmd | wc -l)
5834         [ $nums -eq $expected ] ||
5835                 error "'$cmd' wrong: found $nums, expected $expected"
5836
5837         expected=2
5838         cmd="$LFS find ! -size -5 -type f -lazy $dir"
5839         nums=$($cmd | wc -l)
5840         [ $nums -eq $expected ] ||
5841                 error "'$cmd' wrong: found $nums, expected $expected"
5842         cmd="$LFS find ! -size -5 -type f $dir"
5843         nums=$($cmd | wc -l)
5844         [ $nums -eq $expected ] ||
5845                 error "'$cmd' wrong: found $nums, expected $expected"
5846
5847         expected=12
5848         cmd="$LFS find -size -5 -type f -lazy $dir"
5849         nums=$($cmd | wc -l)
5850         [ $nums -eq $expected ] ||
5851                 error "'$cmd' wrong: found $nums, expected $expected"
5852         cmd="$LFS find -size -5 -type f $dir"
5853         nums=$($cmd | wc -l)
5854         [ $nums -eq $expected ] ||
5855                 error "'$cmd' wrong: found $nums, expected $expected"
5856 }
5857 run_test 56r "check lfs find -size works"
5858
5859 test_56ra() {
5860         local dir=$DIR/$tdir
5861
5862         [[ $OSC == "mdc" ]] && skip "DoM files" && return
5863
5864         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5865
5866         cancel_lru_locks $OSC
5867
5868         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5869         local expected=12
5870         local cmd="$LFS find -size 0 -type f -lazy $dir"
5871         local nums=$($cmd | wc -l)
5872
5873         [ $nums -eq $expected ] ||
5874                 error "'$cmd' wrong: found $nums, expected $expected"
5875
5876         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5877         [ $rpcs_before -eq $rpcs_after ] ||
5878                 error "'$cmd' should not send glimpse RPCs to OST"
5879         cmd="$LFS find -size 0 -type f $dir"
5880         nums=$($cmd | wc -l)
5881         [ $nums -eq $expected ] ||
5882                 error "'$cmd' wrong: found $nums, expected $expected"
5883         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5884         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5885         $LCTL get_param osc.*.stats
5886         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
5887                 error "'$cmd' should send 12 glimpse RPCs to OST"
5888
5889         cancel_lru_locks $OSC
5890         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5891         expected=0
5892         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5893         nums=$($cmd | wc -l)
5894         [ $nums -eq $expected ] ||
5895                 error "'$cmd' wrong: found $nums, expected $expected"
5896         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5897         $LCTL get_param mdc.*.stats
5898         [ $rpcs_before -eq $rpcs_after ] ||
5899                 error "'$cmd' should not send glimpse RPCs to OST"
5900         cmd="$LFS find ! -size 0 -type f $dir"
5901         nums=$($cmd | wc -l)
5902         [ $nums -eq $expected ] ||
5903                 error "'$cmd' wrong: found $nums, expected $expected"
5904         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5905         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5906         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
5907                 error "'$cmd' should send 12 glimpse RPCs to OST"
5908
5909         echo "test" > $dir/$tfile
5910         echo "test2" > $dir/$tfile.2 && sync
5911         cancel_lru_locks $OSC
5912         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5913         expected=1
5914         cmd="$LFS find -size 5 -type f -lazy $dir"
5915         nums=$($cmd | wc -l)
5916         [ $nums -eq $expected ] ||
5917                 error "'$cmd' wrong: found $nums, expected $expected"
5918         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5919         [ $rpcs_before -eq $rpcs_after ] ||
5920                 error "'$cmd' should not send glimpse RPCs to OST"
5921         cmd="$LFS find -size 5 -type f $dir"
5922         nums=$($cmd | wc -l)
5923         [ $nums -eq $expected ] ||
5924                 error "'$cmd' wrong: found $nums, expected $expected"
5925         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5926         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5927         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5928                 error "'$cmd' should send 14 glimpse RPCs to OST"
5929
5930         cancel_lru_locks $OSC
5931         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5932         expected=1
5933         cmd="$LFS find -size +5 -type f -lazy $dir"
5934         nums=$($cmd | wc -l)
5935         [ $nums -eq $expected ] ||
5936                 error "'$cmd' wrong: found $nums, expected $expected"
5937         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5938         [ $rpcs_before -eq $rpcs_after ] ||
5939                 error "'$cmd' should not send glimpse RPCs to OST"
5940         cmd="$LFS find -size +5 -type f $dir"
5941         nums=$($cmd | wc -l)
5942         [ $nums -eq $expected ] ||
5943                 error "'$cmd' wrong: found $nums, expected $expected"
5944         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5945         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5946         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5947                 error "'$cmd' should send 14 glimpse RPCs to OST"
5948
5949         cancel_lru_locks $OSC
5950         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5951         expected=2
5952         cmd="$LFS find -size +0 -type f -lazy $dir"
5953         nums=$($cmd | wc -l)
5954         [ $nums -eq $expected ] ||
5955                 error "'$cmd' wrong: found $nums, expected $expected"
5956         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5957         [ $rpcs_before -eq $rpcs_after ] ||
5958                 error "'$cmd' should not send glimpse RPCs to OST"
5959         cmd="$LFS find -size +0 -type f $dir"
5960         nums=$($cmd | wc -l)
5961         [ $nums -eq $expected ] ||
5962                 error "'$cmd' wrong: found $nums, expected $expected"
5963         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5964         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5965         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5966                 error "'$cmd' should send 14 glimpse RPCs to OST"
5967
5968         cancel_lru_locks $OSC
5969         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5970         expected=2
5971         cmd="$LFS find ! -size -5 -type f -lazy $dir"
5972         nums=$($cmd | wc -l)
5973         [ $nums -eq $expected ] ||
5974                 error "'$cmd' wrong: found $nums, expected $expected"
5975         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5976         [ $rpcs_before -eq $rpcs_after ] ||
5977                 error "'$cmd' should not send glimpse RPCs to OST"
5978         cmd="$LFS find ! -size -5 -type f $dir"
5979         nums=$($cmd | wc -l)
5980         [ $nums -eq $expected ] ||
5981                 error "'$cmd' wrong: found $nums, expected $expected"
5982         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5983         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5984         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5985                 error "'$cmd' should send 14 glimpse RPCs to OST"
5986
5987         cancel_lru_locks $OSC
5988         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5989         expected=12
5990         cmd="$LFS find -size -5 -type f -lazy $dir"
5991         nums=$($cmd | wc -l)
5992         [ $nums -eq $expected ] ||
5993                 error "'$cmd' wrong: found $nums, expected $expected"
5994         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5995         [ $rpcs_before -eq $rpcs_after ] ||
5996                 error "'$cmd' should not send glimpse RPCs to OST"
5997         cmd="$LFS find -size -5 -type f $dir"
5998         nums=$($cmd | wc -l)
5999         [ $nums -eq $expected ] ||
6000                 error "'$cmd' wrong: found $nums, expected $expected"
6001         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6002         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6003         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6004                 error "'$cmd' should send 14 glimpse RPCs to OST"
6005 }
6006 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6007
6008 test_56s() { # LU-611 #LU-9369
6009         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6010
6011         local dir=$DIR/$tdir
6012         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6013
6014         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6015         for i in $(seq $NUMDIRS); do
6016                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6017         done
6018
6019         local expected=$NUMDIRS
6020         local cmd="$LFS find -c $OSTCOUNT $dir"
6021         local nums=$($cmd | wc -l)
6022
6023         [ $nums -eq $expected ] || {
6024                 $LFS getstripe -R $dir
6025                 error "'$cmd' wrong: found $nums, expected $expected"
6026         }
6027
6028         expected=$((NUMDIRS + onestripe))
6029         cmd="$LFS find -stripe-count +0 -type f $dir"
6030         nums=$($cmd | wc -l)
6031         [ $nums -eq $expected ] || {
6032                 $LFS getstripe -R $dir
6033                 error "'$cmd' wrong: found $nums, expected $expected"
6034         }
6035
6036         expected=$onestripe
6037         cmd="$LFS find -stripe-count 1 -type f $dir"
6038         nums=$($cmd | wc -l)
6039         [ $nums -eq $expected ] || {
6040                 $LFS getstripe -R $dir
6041                 error "'$cmd' wrong: found $nums, expected $expected"
6042         }
6043
6044         cmd="$LFS find -stripe-count -2 -type f $dir"
6045         nums=$($cmd | wc -l)
6046         [ $nums -eq $expected ] || {
6047                 $LFS getstripe -R $dir
6048                 error "'$cmd' wrong: found $nums, expected $expected"
6049         }
6050
6051         expected=0
6052         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6053         nums=$($cmd | wc -l)
6054         [ $nums -eq $expected ] || {
6055                 $LFS getstripe -R $dir
6056                 error "'$cmd' wrong: found $nums, expected $expected"
6057         }
6058 }
6059 run_test 56s "check lfs find -stripe-count works"
6060
6061 test_56t() { # LU-611 #LU-9369
6062         local dir=$DIR/$tdir
6063
6064         setup_56 $dir 0 $NUMDIRS
6065         for i in $(seq $NUMDIRS); do
6066                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6067         done
6068
6069         local expected=$NUMDIRS
6070         local cmd="$LFS find -S 8M $dir"
6071         local nums=$($cmd | wc -l)
6072
6073         [ $nums -eq $expected ] || {
6074                 $LFS getstripe -R $dir
6075                 error "'$cmd' wrong: found $nums, expected $expected"
6076         }
6077         rm -rf $dir
6078
6079         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6080
6081         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6082
6083         expected=$(((NUMDIRS + 1) * NUMFILES))
6084         cmd="$LFS find -stripe-size 512k -type f $dir"
6085         nums=$($cmd | wc -l)
6086         [ $nums -eq $expected ] ||
6087                 error "'$cmd' wrong: found $nums, expected $expected"
6088
6089         cmd="$LFS find -stripe-size +320k -type f $dir"
6090         nums=$($cmd | wc -l)
6091         [ $nums -eq $expected ] ||
6092                 error "'$cmd' wrong: found $nums, expected $expected"
6093
6094         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6095         cmd="$LFS find -stripe-size +200k -type f $dir"
6096         nums=$($cmd | wc -l)
6097         [ $nums -eq $expected ] ||
6098                 error "'$cmd' wrong: found $nums, expected $expected"
6099
6100         cmd="$LFS find -stripe-size -640k -type f $dir"
6101         nums=$($cmd | wc -l)
6102         [ $nums -eq $expected ] ||
6103                 error "'$cmd' wrong: found $nums, expected $expected"
6104
6105         expected=4
6106         cmd="$LFS find -stripe-size 256k -type f $dir"
6107         nums=$($cmd | wc -l)
6108         [ $nums -eq $expected ] ||
6109                 error "'$cmd' wrong: found $nums, expected $expected"
6110
6111         cmd="$LFS find -stripe-size -320k -type f $dir"
6112         nums=$($cmd | wc -l)
6113         [ $nums -eq $expected ] ||
6114                 error "'$cmd' wrong: found $nums, expected $expected"
6115
6116         expected=0
6117         cmd="$LFS find -stripe-size 1024k -type f $dir"
6118         nums=$($cmd | wc -l)
6119         [ $nums -eq $expected ] ||
6120                 error "'$cmd' wrong: found $nums, expected $expected"
6121 }
6122 run_test 56t "check lfs find -stripe-size works"
6123
6124 test_56u() { # LU-611
6125         local dir=$DIR/$tdir
6126
6127         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6128
6129         if [[ $OSTCOUNT -gt 1 ]]; then
6130                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6131                 onestripe=4
6132         else
6133                 onestripe=0
6134         fi
6135
6136         local expected=$(((NUMDIRS + 1) * NUMFILES))
6137         local cmd="$LFS find -stripe-index 0 -type f $dir"
6138         local nums=$($cmd | wc -l)
6139
6140         [ $nums -eq $expected ] ||
6141                 error "'$cmd' wrong: found $nums, expected $expected"
6142
6143         expected=$onestripe
6144         cmd="$LFS find -stripe-index 1 -type f $dir"
6145         nums=$($cmd | wc -l)
6146         [ $nums -eq $expected ] ||
6147                 error "'$cmd' wrong: found $nums, expected $expected"
6148
6149         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6150         nums=$($cmd | wc -l)
6151         [ $nums -eq $expected ] ||
6152                 error "'$cmd' wrong: found $nums, expected $expected"
6153
6154         expected=0
6155         # This should produce an error and not return any files
6156         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6157         nums=$($cmd 2>/dev/null | wc -l)
6158         [ $nums -eq $expected ] ||
6159                 error "'$cmd' wrong: found $nums, expected $expected"
6160
6161         if [[ $OSTCOUNT -gt 1 ]]; then
6162                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6163                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6164                 nums=$($cmd | wc -l)
6165                 [ $nums -eq $expected ] ||
6166                         error "'$cmd' wrong: found $nums, expected $expected"
6167         fi
6168 }
6169 run_test 56u "check lfs find -stripe-index works"
6170
6171 test_56v() {
6172         local mdt_idx=0
6173         local dir=$DIR/$tdir
6174
6175         setup_56 $dir $NUMFILES $NUMDIRS
6176
6177         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6178         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6179
6180         for file in $($LFS find -m $UUID $dir); do
6181                 file_midx=$($LFS getstripe -m $file)
6182                 [ $file_midx -eq $mdt_idx ] ||
6183                         error "lfs find -m $UUID != getstripe -m $file_midx"
6184         done
6185 }
6186 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6187
6188 test_56w() {
6189         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6191
6192         local dir=$DIR/$tdir
6193
6194         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6195
6196         local stripe_size=$($LFS getstripe -S -d $dir) ||
6197                 error "$LFS getstripe -S -d $dir failed"
6198         stripe_size=${stripe_size%% *}
6199
6200         local file_size=$((stripe_size * OSTCOUNT))
6201         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6202         local required_space=$((file_num * file_size))
6203         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6204                            head -n1)
6205         [[ $free_space -le $((required_space / 1024)) ]] &&
6206                 skip_env "need $required_space, have $free_space kbytes"
6207
6208         local dd_bs=65536
6209         local dd_count=$((file_size / dd_bs))
6210
6211         # write data into the files
6212         local i
6213         local j
6214         local file
6215
6216         for i in $(seq $NUMFILES); do
6217                 file=$dir/file$i
6218                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6219                         error "write data into $file failed"
6220         done
6221         for i in $(seq $NUMDIRS); do
6222                 for j in $(seq $NUMFILES); do
6223                         file=$dir/dir$i/file$j
6224                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6225                                 error "write data into $file failed"
6226                 done
6227         done
6228
6229         # $LFS_MIGRATE will fail if hard link migration is unsupported
6230         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
6231                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6232                         error "creating links to $dir/dir1/file1 failed"
6233         fi
6234
6235         local expected=-1
6236
6237         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6238
6239         # lfs_migrate file
6240         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6241
6242         echo "$cmd"
6243         eval $cmd || error "$cmd failed"
6244
6245         check_stripe_count $dir/file1 $expected
6246
6247         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6248         then
6249                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6250                 # OST 1 if it is on OST 0. This file is small enough to
6251                 # be on only one stripe.
6252                 file=$dir/migr_1_ost
6253                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6254                         error "write data into $file failed"
6255                 local obdidx=$($LFS getstripe -i $file)
6256                 local oldmd5=$(md5sum $file)
6257                 local newobdidx=0
6258
6259                 [[ $obdidx -eq 0 ]] && newobdidx=1
6260                 cmd="$LFS migrate -i $newobdidx $file"
6261                 echo $cmd
6262                 eval $cmd || error "$cmd failed"
6263
6264                 local realobdix=$($LFS getstripe -i $file)
6265                 local newmd5=$(md5sum $file)
6266
6267                 [[ $newobdidx -ne $realobdix ]] &&
6268                         error "new OST is different (was=$obdidx, "\
6269                               "wanted=$newobdidx, got=$realobdix)"
6270                 [[ "$oldmd5" != "$newmd5" ]] &&
6271                         error "md5sum differ: $oldmd5, $newmd5"
6272         fi
6273
6274         # lfs_migrate dir
6275         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6276         echo "$cmd"
6277         eval $cmd || error "$cmd failed"
6278
6279         for j in $(seq $NUMFILES); do
6280                 check_stripe_count $dir/dir1/file$j $expected
6281         done
6282
6283         # lfs_migrate works with lfs find
6284         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6285              $LFS_MIGRATE -y -c $expected"
6286         echo "$cmd"
6287         eval $cmd || error "$cmd failed"
6288
6289         for i in $(seq 2 $NUMFILES); do
6290                 check_stripe_count $dir/file$i $expected
6291         done
6292         for i in $(seq 2 $NUMDIRS); do
6293                 for j in $(seq $NUMFILES); do
6294                 check_stripe_count $dir/dir$i/file$j $expected
6295                 done
6296         done
6297 }
6298 run_test 56w "check lfs_migrate -c stripe_count works"
6299
6300 test_56wb() {
6301         local file1=$DIR/$tdir/file1
6302         local create_pool=false
6303         local initial_pool=$($LFS getstripe -p $DIR)
6304         local pool_list=()
6305         local pool=""
6306
6307         echo -n "Creating test dir..."
6308         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6309         echo "done."
6310
6311         echo -n "Creating test file..."
6312         touch $file1 || error "cannot create file"
6313         echo "done."
6314
6315         echo -n "Detecting existing pools..."
6316         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6317
6318         if [ ${#pool_list[@]} -gt 0 ]; then
6319                 echo "${pool_list[@]}"
6320                 for thispool in "${pool_list[@]}"; do
6321                         if [[ -z "$initial_pool" ||
6322                               "$initial_pool" != "$thispool" ]]; then
6323                                 pool="$thispool"
6324                                 echo "Using existing pool '$pool'"
6325                                 break
6326                         fi
6327                 done
6328         else
6329                 echo "none detected."
6330         fi
6331         if [ -z "$pool" ]; then
6332                 pool=${POOL:-testpool}
6333                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6334                 echo -n "Creating pool '$pool'..."
6335                 create_pool=true
6336                 pool_add $pool &> /dev/null ||
6337                         error "pool_add failed"
6338                 echo "done."
6339
6340                 echo -n "Adding target to pool..."
6341                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6342                         error "pool_add_targets failed"
6343                 echo "done."
6344         fi
6345
6346         echo -n "Setting pool using -p option..."
6347         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6348                 error "migrate failed rc = $?"
6349         echo "done."
6350
6351         echo -n "Verifying test file is in pool after migrating..."
6352         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6353                 error "file was not migrated to pool $pool"
6354         echo "done."
6355
6356         echo -n "Removing test file from pool '$pool'..."
6357         $LFS migrate $file1 &> /dev/null ||
6358                 error "cannot remove from pool"
6359         [ "$($LFS getstripe -p $file1)" ] &&
6360                 error "pool still set"
6361         echo "done."
6362
6363         echo -n "Setting pool using --pool option..."
6364         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6365                 error "migrate failed rc = $?"
6366         echo "done."
6367
6368         # Clean up
6369         rm -f $file1
6370         if $create_pool; then
6371                 destroy_test_pools 2> /dev/null ||
6372                         error "destroy test pools failed"
6373         fi
6374 }
6375 run_test 56wb "check lfs_migrate pool support"
6376
6377 test_56wc() {
6378         local file1="$DIR/$tdir/file1"
6379
6380         echo -n "Creating test dir..."
6381         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6382         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6383         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6384                 error "cannot set stripe"
6385         echo "done"
6386
6387         echo -n "Setting initial stripe for test file..."
6388         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6389                 error "cannot set stripe"
6390         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6391                 error "stripe size not set"
6392         echo "done."
6393
6394         # File currently set to -S 512K -c 1
6395
6396         # Ensure -c and -S options are rejected when -R is set
6397         echo -n "Verifying incompatible options are detected..."
6398         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6399                 error "incompatible -c and -R options not detected"
6400         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6401                 error "incompatible -S and -R options not detected"
6402         echo "done."
6403
6404         # Ensure unrecognized options are passed through to 'lfs migrate'
6405         echo -n "Verifying -S option is passed through to lfs migrate..."
6406         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6407                 error "migration failed"
6408         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6409                 error "file was not restriped"
6410         echo "done."
6411
6412         # File currently set to -S 1M -c 1
6413
6414         # Ensure long options are supported
6415         echo -n "Verifying long options supported..."
6416         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6417                 error "long option without argument not supported"
6418         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6419                 error "long option with argument not supported"
6420         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6421                 error "file not restriped with --stripe-size option"
6422         echo "done."
6423
6424         # File currently set to -S 512K -c 1
6425
6426         if [ "$OSTCOUNT" -gt 1 ]; then
6427                 echo -n "Verifying explicit stripe count can be set..."
6428                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6429                         error "migrate failed"
6430                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6431                         error "file not restriped to explicit count"
6432                 echo "done."
6433         fi
6434
6435         # File currently set to -S 512K -c 1 or -S 512K -c 2
6436
6437         # Ensure parent striping is used if -R is set, and no stripe
6438         # count or size is specified
6439         echo -n "Setting stripe for parent directory..."
6440         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6441                 error "cannot set stripe"
6442         echo "done."
6443
6444         echo -n "Verifying restripe option uses parent stripe settings..."
6445         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6446                 error "migrate failed"
6447         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6448                 error "file not restriped to parent settings"
6449         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6450                 error "file not restriped to parent settings"
6451         echo "done."
6452
6453         # File currently set to -S 1M -c 1
6454
6455         # Ensure striping is preserved if -R is not set, and no stripe
6456         # count or size is specified
6457         echo -n "Verifying striping size preserved when not specified..."
6458         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6459         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6460                 error "cannot set stripe on parent directory"
6461         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6462                 error "migrate failed"
6463         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6464                 error "file was restriped"
6465         echo "done."
6466
6467         # Ensure file name properly detected when final option has no argument
6468         echo -n "Verifying file name properly detected..."
6469         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6470                 error "file name interpreted as option argument"
6471         echo "done."
6472
6473         # Clean up
6474         rm -f "$file1"
6475 }
6476 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6477
6478 test_56wd() {
6479         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6480
6481         local file1=$DIR/$tdir/file1
6482
6483         echo -n "Creating test dir..."
6484         test_mkdir $DIR/$tdir || error "cannot create dir"
6485         echo "done."
6486
6487         echo -n "Creating test file..."
6488         touch $file1
6489         echo "done."
6490
6491         # Ensure 'lfs migrate' will fail by using a non-existent option,
6492         # and make sure rsync is not called to recover
6493         echo -n "Make sure --no-rsync option works..."
6494         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6495                 grep -q 'refusing to fall back to rsync' ||
6496                 error "rsync was called with --no-rsync set"
6497         echo "done."
6498
6499         # Ensure rsync is called without trying 'lfs migrate' first
6500         echo -n "Make sure --rsync option works..."
6501         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6502                 grep -q 'falling back to rsync' &&
6503                 error "lfs migrate was called with --rsync set"
6504         echo "done."
6505
6506         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6507         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6508                 grep -q 'at the same time' ||
6509                 error "--rsync and --no-rsync accepted concurrently"
6510         echo "done."
6511
6512         # Clean up
6513         rm -f $file1
6514 }
6515 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6516
6517 test_56x() {
6518         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6519         check_swap_layouts_support
6520
6521         local dir=$DIR/$tdir
6522         local ref1=/etc/passwd
6523         local file1=$dir/file1
6524
6525         test_mkdir $dir || error "creating dir $dir"
6526         $LFS setstripe -c 2 $file1
6527         cp $ref1 $file1
6528         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6529         stripe=$($LFS getstripe -c $file1)
6530         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6531         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6532
6533         # clean up
6534         rm -f $file1
6535 }
6536 run_test 56x "lfs migration support"
6537
6538 test_56xa() {
6539         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6540         check_swap_layouts_support
6541
6542         local dir=$DIR/$tdir/$testnum
6543
6544         test_mkdir -p $dir
6545
6546         local ref1=/etc/passwd
6547         local file1=$dir/file1
6548
6549         $LFS setstripe -c 2 $file1
6550         cp $ref1 $file1
6551         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6552
6553         local stripe=$($LFS getstripe -c $file1)
6554
6555         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6556         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6557
6558         # clean up
6559         rm -f $file1
6560 }
6561 run_test 56xa "lfs migration --block support"
6562
6563 check_migrate_links() {
6564         local dir="$1"
6565         local file1="$dir/file1"
6566         local begin="$2"
6567         local count="$3"
6568         local total_count=$(($begin + $count - 1))
6569         local symlink_count=10
6570         local uniq_count=10
6571
6572         if [ ! -f "$file1" ]; then
6573                 echo -n "creating initial file..."
6574                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6575                         error "cannot setstripe initial file"
6576                 echo "done"
6577
6578                 echo -n "creating symlinks..."
6579                 for s in $(seq 1 $symlink_count); do
6580                         ln -s "$file1" "$dir/slink$s" ||
6581                                 error "cannot create symlinks"
6582                 done
6583                 echo "done"
6584
6585                 echo -n "creating nonlinked files..."
6586                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6587                         error "cannot create nonlinked files"
6588                 echo "done"
6589         fi
6590
6591         # create hard links
6592         if [ ! -f "$dir/file$total_count" ]; then
6593                 echo -n "creating hard links $begin:$total_count..."
6594                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6595                         /dev/null || error "cannot create hard links"
6596                 echo "done"
6597         fi
6598
6599         echo -n "checking number of hard links listed in xattrs..."
6600         local fid=$($LFS getstripe -F "$file1")
6601         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6602
6603         echo "${#paths[*]}"
6604         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6605                         skip "hard link list has unexpected size, skipping test"
6606         fi
6607         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6608                         error "link names should exceed xattrs size"
6609         fi
6610
6611         echo -n "migrating files..."
6612         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
6613         local rc=$?
6614         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6615         echo "done"
6616
6617         # make sure all links have been properly migrated
6618         echo -n "verifying files..."
6619         fid=$($LFS getstripe -F "$file1") ||
6620                 error "cannot get fid for file $file1"
6621         for i in $(seq 2 $total_count); do
6622                 local fid2=$($LFS getstripe -F $dir/file$i)
6623
6624                 [ "$fid2" == "$fid" ] ||
6625                         error "migrated hard link has mismatched FID"
6626         done
6627
6628         # make sure hard links were properly detected, and migration was
6629         # performed only once for the entire link set; nonlinked files should
6630         # also be migrated
6631         local actual=$(grep -c 'done' <<< "$migrate_out")
6632         local expected=$(($uniq_count + 1))
6633
6634         [ "$actual" -eq  "$expected" ] ||
6635                 error "hard links individually migrated ($actual != $expected)"
6636
6637         # make sure the correct number of hard links are present
6638         local hardlinks=$(stat -c '%h' "$file1")
6639
6640         [ $hardlinks -eq $total_count ] ||
6641                 error "num hard links $hardlinks != $total_count"
6642         echo "done"
6643
6644         return 0
6645 }
6646
6647 test_56xb() {
6648         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6649                 skip "Need MDS version at least 2.10.55"
6650
6651         local dir="$DIR/$tdir"
6652
6653         test_mkdir "$dir" || error "cannot create dir $dir"
6654
6655         echo "testing lfs migrate mode when all links fit within xattrs"
6656         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6657
6658         echo "testing rsync mode when all links fit within xattrs"
6659         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6660
6661         echo "testing lfs migrate mode when all links do not fit within xattrs"
6662         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6663
6664         echo "testing rsync mode when all links do not fit within xattrs"
6665         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6666
6667
6668         # clean up
6669         rm -rf $dir
6670 }
6671 run_test 56xb "lfs migration hard link support"
6672
6673 test_56xc() {
6674         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6675
6676         local dir="$DIR/$tdir"
6677
6678         test_mkdir "$dir" || error "cannot create dir $dir"
6679
6680         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6681         echo -n "Setting initial stripe for 20MB test file..."
6682         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6683                 error "cannot setstripe 20MB file"
6684         echo "done"
6685         echo -n "Sizing 20MB test file..."
6686         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6687         echo "done"
6688         echo -n "Verifying small file autostripe count is 1..."
6689         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6690                 error "cannot migrate 20MB file"
6691         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6692                 error "cannot get stripe for $dir/20mb"
6693         [ $stripe_count -eq 1 ] ||
6694                 error "unexpected stripe count $stripe_count for 20MB file"
6695         rm -f "$dir/20mb"
6696         echo "done"
6697
6698         # Test 2: File is small enough to fit within the available space on
6699         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6700         # have at least an additional 1KB for each desired stripe for test 3
6701         echo -n "Setting stripe for 1GB test file..."
6702         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
6703         echo "done"
6704         echo -n "Sizing 1GB test file..."
6705         # File size is 1GB + 3KB
6706         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
6707         echo "done"
6708
6709         # need at least 512MB per OST for 1GB file to fit in 2 stripes
6710         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
6711         if (( avail > 524288 * OSTCOUNT )); then
6712                 echo -n "Migrating 1GB file..."
6713                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
6714                         error "cannot migrate 1GB file"
6715                 echo "done"
6716                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
6717                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6718                         error "cannot getstripe for 1GB file"
6719                 [ $stripe_count -eq 2 ] ||
6720                         error "unexpected stripe count $stripe_count != 2"
6721                 echo "done"
6722         fi
6723
6724         # Test 3: File is too large to fit within the available space on
6725         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6726         if [ $OSTCOUNT -ge 3 ]; then
6727                 # The required available space is calculated as
6728                 # file size (1GB + 3KB) / OST count (3).
6729                 local kb_per_ost=349526
6730
6731                 echo -n "Migrating 1GB file with limit..."
6732                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
6733                         error "cannot migrate 1GB file with limit"
6734                 echo "done"
6735
6736                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6737                 echo -n "Verifying 1GB autostripe count with limited space..."
6738                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
6739                         error "unexpected stripe count $stripe_count (min 3)"
6740                 echo "done"
6741         fi
6742
6743         # clean up
6744         rm -rf $dir
6745 }
6746 run_test 56xc "lfs migration autostripe"
6747
6748 test_56y() {
6749         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6750                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6751
6752         local res=""
6753         local dir=$DIR/$tdir
6754         local f1=$dir/file1
6755         local f2=$dir/file2
6756
6757         test_mkdir -p $dir || error "creating dir $dir"
6758         touch $f1 || error "creating std file $f1"
6759         $MULTIOP $f2 H2c || error "creating released file $f2"
6760
6761         # a directory can be raid0, so ask only for files
6762         res=$($LFS find $dir -L raid0 -type f | wc -l)
6763         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6764
6765         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6766         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6767
6768         # only files can be released, so no need to force file search
6769         res=$($LFS find $dir -L released)
6770         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6771
6772         res=$($LFS find $dir -type f \! -L released)
6773         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6774 }
6775 run_test 56y "lfs find -L raid0|released"
6776
6777 test_56z() { # LU-4824
6778         # This checks to make sure 'lfs find' continues after errors
6779         # There are two classes of errors that should be caught:
6780         # - If multiple paths are provided, all should be searched even if one
6781         #   errors out
6782         # - If errors are encountered during the search, it should not terminate
6783         #   early
6784         local dir=$DIR/$tdir
6785         local i
6786
6787         test_mkdir $dir
6788         for i in d{0..9}; do
6789                 test_mkdir $dir/$i
6790                 touch $dir/$i/$tfile
6791         done
6792         $LFS find $DIR/non_existent_dir $dir &&
6793                 error "$LFS find did not return an error"
6794         # Make a directory unsearchable. This should NOT be the last entry in
6795         # directory order.  Arbitrarily pick the 6th entry
6796         chmod 700 $($LFS find $dir -type d | sed '6!d')
6797
6798         $RUNAS $LFS find $DIR/non_existent $dir
6799         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6800
6801         # The user should be able to see 10 directories and 9 files
6802         (( count == 19 )) ||
6803                 error "$LFS find found $count != 19 entries after error"
6804 }
6805 run_test 56z "lfs find should continue after an error"
6806
6807 test_56aa() { # LU-5937
6808         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6809
6810         local dir=$DIR/$tdir
6811
6812         mkdir $dir
6813         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6814
6815         createmany -o $dir/striped_dir/${tfile}- 1024
6816         local dirs=$($LFS find --size +8k $dir/)
6817
6818         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6819 }
6820 run_test 56aa "lfs find --size under striped dir"
6821
6822 test_56ab() { # LU-10705
6823         test_mkdir $DIR/$tdir
6824         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6825         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6826         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6827         # Flush writes to ensure valid blocks.  Need to be more thorough for
6828         # ZFS, since blocks are not allocated/returned to client immediately.
6829         sync_all_data
6830         wait_zfs_commit ost1 2
6831         cancel_lru_locks osc
6832         ls -ls $DIR/$tdir
6833
6834         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6835
6836         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6837
6838         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6839         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6840
6841         rm -f $DIR/$tdir/$tfile.[123]
6842 }
6843 run_test 56ab "lfs find --blocks"
6844
6845 test_56ba() {
6846         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6847                 skip "Need MDS version at least 2.10.50"
6848
6849         # Create composite files with one component
6850         local dir=$DIR/$tdir
6851
6852         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6853         # Create composite files with three components
6854         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6855         # Create non-composite files
6856         createmany -o $dir/${tfile}- 10
6857
6858         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6859
6860         [[ $nfiles == 10 ]] ||
6861                 error "lfs find -E 1M found $nfiles != 10 files"
6862
6863         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6864         [[ $nfiles == 25 ]] ||
6865                 error "lfs find ! -E 1M found $nfiles != 25 files"
6866
6867         # All files have a component that starts at 0
6868         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6869         [[ $nfiles == 35 ]] ||
6870                 error "lfs find --component-start 0 - $nfiles != 35 files"
6871
6872         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6873         [[ $nfiles == 15 ]] ||
6874                 error "lfs find --component-start 2M - $nfiles != 15 files"
6875
6876         # All files created here have a componenet that does not starts at 2M
6877         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6878         [[ $nfiles == 35 ]] ||
6879                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6880
6881         # Find files with a specified number of components
6882         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6883         [[ $nfiles == 15 ]] ||
6884                 error "lfs find --component-count 3 - $nfiles != 15 files"
6885
6886         # Remember non-composite files have a component count of zero
6887         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6888         [[ $nfiles == 10 ]] ||
6889                 error "lfs find --component-count 0 - $nfiles != 10 files"
6890
6891         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6892         [[ $nfiles == 20 ]] ||
6893                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6894
6895         # All files have a flag called "init"
6896         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6897         [[ $nfiles == 35 ]] ||
6898                 error "lfs find --component-flags init - $nfiles != 35 files"
6899
6900         # Multi-component files will have a component not initialized
6901         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6902         [[ $nfiles == 15 ]] ||
6903                 error "lfs find !--component-flags init - $nfiles != 15 files"
6904
6905         rm -rf $dir
6906
6907 }
6908 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6909
6910 test_56ca() {
6911         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6912                 skip "Need MDS version at least 2.10.57"
6913
6914         local td=$DIR/$tdir
6915         local tf=$td/$tfile
6916         local dir
6917         local nfiles
6918         local cmd
6919         local i
6920         local j
6921
6922         # create mirrored directories and mirrored files
6923         mkdir $td || error "mkdir $td failed"
6924         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6925         createmany -o $tf- 10 || error "create $tf- failed"
6926
6927         for i in $(seq 2); do
6928                 dir=$td/dir$i
6929                 mkdir $dir || error "mkdir $dir failed"
6930                 $LFS mirror create -N$((3 + i)) $dir ||
6931                         error "create mirrored dir $dir failed"
6932                 createmany -o $dir/$tfile- 10 ||
6933                         error "create $dir/$tfile- failed"
6934         done
6935
6936         # change the states of some mirrored files
6937         echo foo > $tf-6
6938         for i in $(seq 2); do
6939                 dir=$td/dir$i
6940                 for j in $(seq 4 9); do
6941                         echo foo > $dir/$tfile-$j
6942                 done
6943         done
6944
6945         # find mirrored files with specific mirror count
6946         cmd="$LFS find --mirror-count 3 --type f $td"
6947         nfiles=$($cmd | wc -l)
6948         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6949
6950         cmd="$LFS find ! --mirror-count 3 --type f $td"
6951         nfiles=$($cmd | wc -l)
6952         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6953
6954         cmd="$LFS find --mirror-count +2 --type f $td"
6955         nfiles=$($cmd | wc -l)
6956         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6957
6958         cmd="$LFS find --mirror-count -6 --type f $td"
6959         nfiles=$($cmd | wc -l)
6960         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6961
6962         # find mirrored files with specific file state
6963         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6964         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6965
6966         cmd="$LFS find --mirror-state=ro --type f $td"
6967         nfiles=$($cmd | wc -l)
6968         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6969
6970         cmd="$LFS find ! --mirror-state=ro --type f $td"
6971         nfiles=$($cmd | wc -l)
6972         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6973
6974         cmd="$LFS find --mirror-state=wp --type f $td"
6975         nfiles=$($cmd | wc -l)
6976         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6977
6978         cmd="$LFS find ! --mirror-state=sp --type f $td"
6979         nfiles=$($cmd | wc -l)
6980         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6981 }
6982 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6983
6984 test_57a() {
6985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6986         # note test will not do anything if MDS is not local
6987         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6988                 skip_env "ldiskfs only test"
6989         fi
6990         remote_mds_nodsh && skip "remote MDS with nodsh"
6991
6992         local MNTDEV="osd*.*MDT*.mntdev"
6993         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6994         [ -z "$DEV" ] && error "can't access $MNTDEV"
6995         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6996                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6997                         error "can't access $DEV"
6998                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6999                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7000                 rm $TMP/t57a.dump
7001         done
7002 }
7003 run_test 57a "verify MDS filesystem created with large inodes =="
7004
7005 test_57b() {
7006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7007         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7008                 skip_env "ldiskfs only test"
7009         fi
7010         remote_mds_nodsh && skip "remote MDS with nodsh"
7011
7012         local dir=$DIR/$tdir
7013         local filecount=100
7014         local file1=$dir/f1
7015         local fileN=$dir/f$filecount
7016
7017         rm -rf $dir || error "removing $dir"
7018         test_mkdir -c1 $dir
7019         local mdtidx=$($LFS getstripe -m $dir)
7020         local mdtname=MDT$(printf %04x $mdtidx)
7021         local facet=mds$((mdtidx + 1))
7022
7023         echo "mcreating $filecount files"
7024         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7025
7026         # verify that files do not have EAs yet
7027         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7028                 error "$file1 has an EA"
7029         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7030                 error "$fileN has an EA"
7031
7032         sync
7033         sleep 1
7034         df $dir  #make sure we get new statfs data
7035         local mdsfree=$(do_facet $facet \
7036                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7037         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7038         local file
7039
7040         echo "opening files to create objects/EAs"
7041         for file in $(seq -f $dir/f%g 1 $filecount); do
7042                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7043                         error "opening $file"
7044         done
7045
7046         # verify that files have EAs now
7047         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7048         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7049
7050         sleep 1  #make sure we get new statfs data
7051         df $dir
7052         local mdsfree2=$(do_facet $facet \
7053                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7054         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7055
7056         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7057                 if [ "$mdsfree" != "$mdsfree2" ]; then
7058                         error "MDC before $mdcfree != after $mdcfree2"
7059                 else
7060                         echo "MDC before $mdcfree != after $mdcfree2"
7061                         echo "unable to confirm if MDS has large inodes"
7062                 fi
7063         fi
7064         rm -rf $dir
7065 }
7066 run_test 57b "default LOV EAs are stored inside large inodes ==="
7067
7068 test_58() {
7069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7070         [ -z "$(which wiretest 2>/dev/null)" ] &&
7071                         skip_env "could not find wiretest"
7072
7073         wiretest
7074 }
7075 run_test 58 "verify cross-platform wire constants =============="
7076
7077 test_59() {
7078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7079
7080         echo "touch 130 files"
7081         createmany -o $DIR/f59- 130
7082         echo "rm 130 files"
7083         unlinkmany $DIR/f59- 130
7084         sync
7085         # wait for commitment of removal
7086         wait_delete_completed
7087 }
7088 run_test 59 "verify cancellation of llog records async ========="
7089
7090 TEST60_HEAD="test_60 run $RANDOM"
7091 test_60a() {
7092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7093         remote_mgs_nodsh && skip "remote MGS with nodsh"
7094         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7095                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7096                         skip_env "missing subtest run-llog.sh"
7097
7098         log "$TEST60_HEAD - from kernel mode"
7099         do_facet mgs "$LCTL dk > /dev/null"
7100         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7101         do_facet mgs $LCTL dk > $TMP/$tfile
7102
7103         # LU-6388: test llog_reader
7104         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7105         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7106         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7107                         skip_env "missing llog_reader"
7108         local fstype=$(facet_fstype mgs)
7109         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7110                 skip_env "Only for ldiskfs or zfs type mgs"
7111
7112         local mntpt=$(facet_mntpt mgs)
7113         local mgsdev=$(mgsdevname 1)
7114         local fid_list
7115         local fid
7116         local rec_list
7117         local rec
7118         local rec_type
7119         local obj_file
7120         local path
7121         local seq
7122         local oid
7123         local pass=true
7124
7125         #get fid and record list
7126         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7127                 tail -n 4))
7128         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7129                 tail -n 4))
7130         #remount mgs as ldiskfs or zfs type
7131         stop mgs || error "stop mgs failed"
7132         mount_fstype mgs || error "remount mgs failed"
7133         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7134                 fid=${fid_list[i]}
7135                 rec=${rec_list[i]}
7136                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7137                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7138                 oid=$((16#$oid))
7139
7140                 case $fstype in
7141                         ldiskfs )
7142                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7143                         zfs )
7144                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7145                 esac
7146                 echo "obj_file is $obj_file"
7147                 do_facet mgs $llog_reader $obj_file
7148
7149                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7150                         awk '{ print $3 }' | sed -e "s/^type=//g")
7151                 if [ $rec_type != $rec ]; then
7152                         echo "FAILED test_60a wrong record type $rec_type," \
7153                               "should be $rec"
7154                         pass=false
7155                         break
7156                 fi
7157
7158                 #check obj path if record type is LLOG_LOGID_MAGIC
7159                 if [ "$rec" == "1064553b" ]; then
7160                         path=$(do_facet mgs $llog_reader $obj_file |
7161                                 grep "path=" | awk '{ print $NF }' |
7162                                 sed -e "s/^path=//g")
7163                         if [ $obj_file != $mntpt/$path ]; then
7164                                 echo "FAILED test_60a wrong obj path" \
7165                                       "$montpt/$path, should be $obj_file"
7166                                 pass=false
7167                                 break
7168                         fi
7169                 fi
7170         done
7171         rm -f $TMP/$tfile
7172         #restart mgs before "error", otherwise it will block the next test
7173         stop mgs || error "stop mgs failed"
7174         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7175         $pass || error "test failed, see FAILED test_60a messages for specifics"
7176 }
7177 run_test 60a "llog_test run from kernel module and test llog_reader"
7178
7179 test_60b() { # bug 6411
7180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7181
7182         dmesg > $DIR/$tfile
7183         LLOG_COUNT=$(do_facet mgs dmesg |
7184                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7185                           /llog_[a-z]*.c:[0-9]/ {
7186                                 if (marker)
7187                                         from_marker++
7188                                 from_begin++
7189                           }
7190                           END {
7191                                 if (marker)
7192                                         print from_marker
7193                                 else
7194                                         print from_begin
7195                           }")
7196
7197         [[ $LLOG_COUNT -gt 120 ]] &&
7198                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7199 }
7200 run_test 60b "limit repeated messages from CERROR/CWARN"
7201
7202 test_60c() {
7203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7204
7205         echo "create 5000 files"
7206         createmany -o $DIR/f60c- 5000
7207 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7208         lctl set_param fail_loc=0x80000137
7209         unlinkmany $DIR/f60c- 5000
7210         lctl set_param fail_loc=0
7211 }
7212 run_test 60c "unlink file when mds full"
7213
7214 test_60d() {
7215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7216
7217         SAVEPRINTK=$(lctl get_param -n printk)
7218         # verify "lctl mark" is even working"
7219         MESSAGE="test message ID $RANDOM $$"
7220         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7221         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7222
7223         lctl set_param printk=0 || error "set lnet.printk failed"
7224         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7225         MESSAGE="new test message ID $RANDOM $$"
7226         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7227         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7228         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7229
7230         lctl set_param -n printk="$SAVEPRINTK"
7231 }
7232 run_test 60d "test printk console message masking"
7233
7234 test_60e() {
7235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7236         remote_mds_nodsh && skip "remote MDS with nodsh"
7237
7238         touch $DIR/$tfile
7239 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7240         do_facet mds1 lctl set_param fail_loc=0x15b
7241         rm $DIR/$tfile
7242 }
7243 run_test 60e "no space while new llog is being created"
7244
7245 test_60g() {
7246         local pid
7247         local i
7248
7249         test_mkdir -c $MDSCOUNT $DIR/$tdir
7250
7251         (
7252                 local index=0
7253                 while true; do
7254                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7255                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7256                                 2>/dev/null
7257                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7258                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7259                         index=$((index + 1))
7260                 done
7261         ) &
7262
7263         pid=$!
7264
7265         for i in {0..100}; do
7266                 # define OBD_FAIL_OSD_TXN_START    0x19a
7267                 local index=$((i % MDSCOUNT + 1))
7268
7269                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7270                         > /dev/null
7271                 usleep 100
7272         done
7273
7274         kill -9 $pid
7275
7276         for i in $(seq $MDSCOUNT); do
7277                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7278         done
7279
7280         mkdir $DIR/$tdir/new || error "mkdir failed"
7281         rmdir $DIR/$tdir/new || error "rmdir failed"
7282
7283         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7284                 -t namespace
7285         for i in $(seq $MDSCOUNT); do
7286                 wait_update_facet mds$i "$LCTL get_param -n \
7287                         mdd.$(facet_svc mds$i).lfsck_namespace |
7288                         awk '/^status/ { print \\\$2 }'" "completed"
7289         done
7290
7291         ls -R $DIR/$tdir || error "ls failed"
7292         rm -rf $DIR/$tdir || error "rmdir failed"
7293 }
7294 run_test 60g "transaction abort won't cause MDT hung"
7295
7296 test_60h() {
7297         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7298                 skip "Need MDS version at least 2.12.52"
7299         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7300
7301         local f
7302
7303         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7304         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7305         for fail_loc in 0x80000188 0x80000189; do
7306                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7307                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7308                         error "mkdir $dir-$fail_loc failed"
7309                 for i in {0..10}; do
7310                         # create may fail on missing stripe
7311                         echo $i > $DIR/$tdir-$fail_loc/$i
7312                 done
7313                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7314                         error "getdirstripe $tdir-$fail_loc failed"
7315                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7316                         error "migrate $tdir-$fail_loc failed"
7317                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7318                         error "getdirstripe $tdir-$fail_loc failed"
7319                 pushd $DIR/$tdir-$fail_loc
7320                 for f in *; do
7321                         echo $f | cmp $f - || error "$f data mismatch"
7322                 done
7323                 popd
7324                 rm -rf $DIR/$tdir-$fail_loc
7325         done
7326 }
7327 run_test 60h "striped directory with missing stripes can be accessed"
7328
7329 test_61a() {
7330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7331
7332         f="$DIR/f61"
7333         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7334         cancel_lru_locks osc
7335         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7336         sync
7337 }
7338 run_test 61a "mmap() writes don't make sync hang ================"
7339
7340 test_61b() {
7341         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7342 }
7343 run_test 61b "mmap() of unstriped file is successful"
7344
7345 # bug 2330 - insufficient obd_match error checking causes LBUG
7346 test_62() {
7347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7348
7349         f="$DIR/f62"
7350         echo foo > $f
7351         cancel_lru_locks osc
7352         lctl set_param fail_loc=0x405
7353         cat $f && error "cat succeeded, expect -EIO"
7354         lctl set_param fail_loc=0
7355 }
7356 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7357 # match every page all of the time.
7358 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7359
7360 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7361 # Though this test is irrelevant anymore, it helped to reveal some
7362 # other grant bugs (LU-4482), let's keep it.
7363 test_63a() {   # was test_63
7364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7365
7366         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7367
7368         for i in `seq 10` ; do
7369                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7370                 sleep 5
7371                 kill $!
7372                 sleep 1
7373         done
7374
7375         rm -f $DIR/f63 || true
7376 }
7377 run_test 63a "Verify oig_wait interruption does not crash ======="
7378
7379 # bug 2248 - async write errors didn't return to application on sync
7380 # bug 3677 - async write errors left page locked
7381 test_63b() {
7382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7383
7384         debugsave
7385         lctl set_param debug=-1
7386
7387         # ensure we have a grant to do async writes
7388         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7389         rm $DIR/$tfile
7390
7391         sync    # sync lest earlier test intercept the fail_loc
7392
7393         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7394         lctl set_param fail_loc=0x80000406
7395         $MULTIOP $DIR/$tfile Owy && \
7396                 error "sync didn't return ENOMEM"
7397         sync; sleep 2; sync     # do a real sync this time to flush page
7398         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7399                 error "locked page left in cache after async error" || true
7400         debugrestore
7401 }
7402 run_test 63b "async write errors should be returned to fsync ==="
7403
7404 test_64a () {
7405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7406
7407         df $DIR
7408         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7409 }
7410 run_test 64a "verify filter grant calculations (in kernel) ====="
7411
7412 test_64b () {
7413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7414
7415         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7416 }
7417 run_test 64b "check out-of-space detection on client"
7418
7419 test_64c() {
7420         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7421 }
7422 run_test 64c "verify grant shrink"
7423
7424 # this does exactly what osc_request.c:osc_announce_cached() does in
7425 # order to calculate max amount of grants to ask from server
7426 want_grant() {
7427         local tgt=$1
7428
7429         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7430         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7431
7432         ((rpc_in_flight ++));
7433         nrpages=$((nrpages * rpc_in_flight))
7434
7435         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7436
7437         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7438
7439         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7440         local undirty=$((nrpages * PAGE_SIZE))
7441
7442         local max_extent_pages
7443         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7444             grep grant_max_extent_size | awk '{print $2}')
7445         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7446         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7447         local grant_extent_tax
7448         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7449             grep grant_extent_tax | awk '{print $2}')
7450
7451         undirty=$((undirty + nrextents * grant_extent_tax))
7452
7453         echo $undirty
7454 }
7455
7456 # this is size of unit for grant allocation. It should be equal to
7457 # what tgt_grant.c:tgt_grant_chunk() calculates
7458 grant_chunk() {
7459         local tgt=$1
7460         local max_brw_size
7461         local grant_extent_tax
7462
7463         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7464             grep max_brw_size | awk '{print $2}')
7465
7466         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7467             grep grant_extent_tax | awk '{print $2}')
7468
7469         echo $(((max_brw_size + grant_extent_tax) * 2))
7470 }
7471
7472 test_64d() {
7473         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7474                 skip "OST < 2.10.55 doesn't limit grants enough"
7475
7476         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7477         local file=$DIR/$tfile
7478
7479         [[ $($LCTL get_param osc.${tgt}.import |
7480              grep "connect_flags:.*grant_param") ]] ||
7481                 skip "no grant_param connect flag"
7482
7483         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7484
7485         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7486
7487         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7488         stack_trap "rm -f $file" EXIT
7489
7490         $LFS setstripe $file -i 0 -c 1
7491         dd if=/dev/zero of=$file bs=1M count=1000 &
7492         ddpid=$!
7493
7494         while true
7495         do
7496                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7497                 if [[ $cur_grant -gt $max_cur_granted ]]
7498                 then
7499                         kill $ddpid
7500                         error "cur_grant $cur_grant > $max_cur_granted"
7501                 fi
7502                 kill -0 $ddpid
7503                 [[ $? -ne 0 ]] && break;
7504                 sleep 2
7505         done
7506
7507         rm -f $DIR/$tfile
7508         wait_delete_completed
7509         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7510 }
7511 run_test 64d "check grant limit exceed"
7512
7513 # bug 1414 - set/get directories' stripe info
7514 test_65a() {
7515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7516
7517         test_mkdir $DIR/$tdir
7518         touch $DIR/$tdir/f1
7519         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7520 }
7521 run_test 65a "directory with no stripe info"
7522
7523 test_65b() {
7524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7525
7526         test_mkdir $DIR/$tdir
7527         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7528
7529         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7530                                                 error "setstripe"
7531         touch $DIR/$tdir/f2
7532         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7533 }
7534 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7535
7536 test_65c() {
7537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7538         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7539
7540         test_mkdir $DIR/$tdir
7541         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7542
7543         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7544                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7545         touch $DIR/$tdir/f3
7546         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7547 }
7548 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7549
7550 test_65d() {
7551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7552
7553         test_mkdir $DIR/$tdir
7554         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7555         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7556
7557         if [[ $STRIPECOUNT -le 0 ]]; then
7558                 sc=1
7559         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7560                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7561                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7562         else
7563                 sc=$(($STRIPECOUNT - 1))
7564         fi
7565         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7566         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7567         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7568                 error "lverify failed"
7569 }
7570 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7571
7572 test_65e() {
7573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7574
7575         test_mkdir $DIR/$tdir
7576
7577         $LFS setstripe $DIR/$tdir || error "setstripe"
7578         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7579                                         error "no stripe info failed"
7580         touch $DIR/$tdir/f6
7581         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7582 }
7583 run_test 65e "directory setstripe defaults"
7584
7585 test_65f() {
7586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7587
7588         test_mkdir $DIR/${tdir}f
7589         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7590                 error "setstripe succeeded" || true
7591 }
7592 run_test 65f "dir setstripe permission (should return error) ==="
7593
7594 test_65g() {
7595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7596
7597         test_mkdir $DIR/$tdir
7598         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7599
7600         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7601                 error "setstripe -S failed"
7602         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7603         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7604                 error "delete default stripe failed"
7605 }
7606 run_test 65g "directory setstripe -d"
7607
7608 test_65h() {
7609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7610
7611         test_mkdir $DIR/$tdir
7612         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7613
7614         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7615                 error "setstripe -S failed"
7616         test_mkdir $DIR/$tdir/dd1
7617         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7618                 error "stripe info inherit failed"
7619 }
7620 run_test 65h "directory stripe info inherit ===================="
7621
7622 test_65i() {
7623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7624
7625         save_layout_restore_at_exit $MOUNT
7626
7627         # bug6367: set non-default striping on root directory
7628         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7629
7630         # bug12836: getstripe on -1 default directory striping
7631         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7632
7633         # bug12836: getstripe -v on -1 default directory striping
7634         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7635
7636         # bug12836: new find on -1 default directory striping
7637         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7638 }
7639 run_test 65i "various tests to set root directory striping"
7640
7641 test_65j() { # bug6367
7642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7643
7644         sync; sleep 1
7645
7646         # if we aren't already remounting for each test, do so for this test
7647         if [ "$I_MOUNTED" = "yes" ]; then
7648                 cleanup || error "failed to unmount"
7649                 setup
7650         fi
7651
7652         save_layout_restore_at_exit $MOUNT
7653
7654         $LFS setstripe -d $MOUNT || error "setstripe failed"
7655 }
7656 run_test 65j "set default striping on root directory (bug 6367)="
7657
7658 cleanup_65k() {
7659         rm -rf $DIR/$tdir
7660         wait_delete_completed
7661         do_facet $SINGLEMDS "lctl set_param -n \
7662                 osp.$ost*MDT0000.max_create_count=$max_count"
7663         do_facet $SINGLEMDS "lctl set_param -n \
7664                 osp.$ost*MDT0000.create_count=$count"
7665         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7666         echo $INACTIVE_OSC "is Activate"
7667
7668         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7669 }
7670
7671 test_65k() { # bug11679
7672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7673         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7674         remote_mds_nodsh && skip "remote MDS with nodsh"
7675
7676         local disable_precreate=true
7677         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7678                 disable_precreate=false
7679
7680         echo "Check OST status: "
7681         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7682                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7683
7684         for OSC in $MDS_OSCS; do
7685                 echo $OSC "is active"
7686                 do_facet $SINGLEMDS lctl --device %$OSC activate
7687         done
7688
7689         for INACTIVE_OSC in $MDS_OSCS; do
7690                 local ost=$(osc_to_ost $INACTIVE_OSC)
7691                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7692                                lov.*md*.target_obd |
7693                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7694
7695                 mkdir -p $DIR/$tdir
7696                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7697                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7698
7699                 echo "Deactivate: " $INACTIVE_OSC
7700                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7701
7702                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7703                               osp.$ost*MDT0000.create_count")
7704                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7705                                   osp.$ost*MDT0000.max_create_count")
7706                 $disable_precreate &&
7707                         do_facet $SINGLEMDS "lctl set_param -n \
7708                                 osp.$ost*MDT0000.max_create_count=0"
7709
7710                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7711                         [ -f $DIR/$tdir/$idx ] && continue
7712                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7713                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7714                                 { cleanup_65k;
7715                                   error "setstripe $idx should succeed"; }
7716                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7717                 done
7718                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7719                 rmdir $DIR/$tdir
7720
7721                 do_facet $SINGLEMDS "lctl set_param -n \
7722                         osp.$ost*MDT0000.max_create_count=$max_count"
7723                 do_facet $SINGLEMDS "lctl set_param -n \
7724                         osp.$ost*MDT0000.create_count=$count"
7725                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7726                 echo $INACTIVE_OSC "is Activate"
7727
7728                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7729         done
7730 }
7731 run_test 65k "validate manual striping works properly with deactivated OSCs"
7732
7733 test_65l() { # bug 12836
7734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7735
7736         test_mkdir -p $DIR/$tdir/test_dir
7737         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7738         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7739 }
7740 run_test 65l "lfs find on -1 stripe dir ========================"
7741
7742 test_65m() {
7743         local layout=$(save_layout $MOUNT)
7744         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7745                 restore_layout $MOUNT $layout
7746                 error "setstripe should fail by non-root users"
7747         }
7748         true
7749 }
7750 run_test 65m "normal user can't set filesystem default stripe"
7751
7752 test_65n() {
7753         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7754         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7755                 skip "Need MDS version at least 2.12.50"
7756         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7757
7758         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7759         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7760         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7761
7762         local root_layout=$(save_layout $MOUNT)
7763         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7764
7765         # new subdirectory under root directory should not inherit
7766         # the default layout from root
7767         local dir1=$MOUNT/$tdir-1
7768         mkdir $dir1 || error "mkdir $dir1 failed"
7769         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7770                 error "$dir1 shouldn't have LOV EA"
7771
7772         # delete the default layout on root directory
7773         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7774
7775         local dir2=$MOUNT/$tdir-2
7776         mkdir $dir2 || error "mkdir $dir2 failed"
7777         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7778                 error "$dir2 shouldn't have LOV EA"
7779
7780         # set a new striping pattern on root directory
7781         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7782         local new_def_stripe_size=$((def_stripe_size * 2))
7783         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7784                 error "set stripe size on $MOUNT failed"
7785
7786         # new file created in $dir2 should inherit the new stripe size from
7787         # the filesystem default
7788         local file2=$dir2/$tfile-2
7789         touch $file2 || error "touch $file2 failed"
7790
7791         local file2_stripe_size=$($LFS getstripe -S $file2)
7792         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7793                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7794
7795         local dir3=$MOUNT/$tdir-3
7796         mkdir $dir3 || error "mkdir $dir3 failed"
7797         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7798                 error "$dir3 shouldn't have LOV EA"
7799
7800         # set OST pool on root directory
7801         local pool=$TESTNAME
7802         pool_add $pool || error "add $pool failed"
7803         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7804                 error "add targets to $pool failed"
7805
7806         $LFS setstripe -p $pool $MOUNT ||
7807                 error "set OST pool on $MOUNT failed"
7808
7809         # new file created in $dir3 should inherit the pool from
7810         # the filesystem default
7811         local file3=$dir3/$tfile-3
7812         touch $file3 || error "touch $file3 failed"
7813
7814         local file3_pool=$($LFS getstripe -p $file3)
7815         [[ "$file3_pool" = "$pool" ]] ||
7816                 error "$file3 didn't inherit OST pool $pool"
7817
7818         local dir4=$MOUNT/$tdir-4
7819         mkdir $dir4 || error "mkdir $dir4 failed"
7820         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7821                 error "$dir4 shouldn't have LOV EA"
7822
7823         # new file created in $dir4 should inherit the pool from
7824         # the filesystem default
7825         local file4=$dir4/$tfile-4
7826         touch $file4 || error "touch $file4 failed"
7827
7828         local file4_pool=$($LFS getstripe -p $file4)
7829         [[ "$file4_pool" = "$pool" ]] ||
7830                 error "$file4 didn't inherit OST pool $pool"
7831
7832         # new subdirectory under non-root directory should inherit
7833         # the default layout from its parent directory
7834         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7835                 error "set directory layout on $dir4 failed"
7836
7837         local dir5=$dir4/$tdir-5
7838         mkdir $dir5 || error "mkdir $dir5 failed"
7839
7840         local dir4_layout=$(get_layout_param $dir4)
7841         local dir5_layout=$(get_layout_param $dir5)
7842         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7843                 error "$dir5 should inherit the default layout from $dir4"
7844
7845         # though subdir under ROOT doesn't inherit default layout, but
7846         # its sub dir/file should be created with default layout.
7847         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
7848         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
7849                 skip "Need MDS version at least 2.12.59"
7850
7851         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
7852         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
7853         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
7854
7855         if [ $default_lmv_hash == "none" ]; then
7856                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
7857         else
7858                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
7859                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
7860         fi
7861
7862         $LFS setdirstripe -D -c 2 $MOUNT ||
7863                 error "setdirstripe -D -c 2 failed"
7864         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
7865         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
7866         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
7867 }
7868 run_test 65n "don't inherit default layout from root for new subdirectories"
7869
7870 # bug 2543 - update blocks count on client
7871 test_66() {
7872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7873
7874         COUNT=${COUNT:-8}
7875         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7876         sync; sync_all_data; sync; sync_all_data
7877         cancel_lru_locks osc
7878         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7879         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7880 }
7881 run_test 66 "update inode blocks count on client ==============="
7882
7883 meminfo() {
7884         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7885 }
7886
7887 swap_used() {
7888         swapon -s | awk '($1 == "'$1'") { print $4 }'
7889 }
7890
7891 # bug5265, obdfilter oa2dentry return -ENOENT
7892 # #define OBD_FAIL_SRV_ENOENT 0x217
7893 test_69() {
7894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7895         remote_ost_nodsh && skip "remote OST with nodsh"
7896
7897         f="$DIR/$tfile"
7898         $LFS setstripe -c 1 -i 0 $f
7899
7900         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7901
7902         do_facet ost1 lctl set_param fail_loc=0x217
7903         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7904         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7905
7906         do_facet ost1 lctl set_param fail_loc=0
7907         $DIRECTIO write $f 0 2 || error "write error"
7908
7909         cancel_lru_locks osc
7910         $DIRECTIO read $f 0 1 || error "read error"
7911
7912         do_facet ost1 lctl set_param fail_loc=0x217
7913         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7914
7915         do_facet ost1 lctl set_param fail_loc=0
7916         rm -f $f
7917 }
7918 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7919
7920 test_71() {
7921         test_mkdir $DIR/$tdir
7922         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7923         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7924 }
7925 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7926
7927 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7929         [ "$RUNAS_ID" = "$UID" ] &&
7930                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7931         # Check that testing environment is properly set up. Skip if not
7932         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7933                 skip_env "User $RUNAS_ID does not exist - skipping"
7934
7935         touch $DIR/$tfile
7936         chmod 777 $DIR/$tfile
7937         chmod ug+s $DIR/$tfile
7938         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7939                 error "$RUNAS dd $DIR/$tfile failed"
7940         # See if we are still setuid/sgid
7941         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7942                 error "S/gid is not dropped on write"
7943         # Now test that MDS is updated too
7944         cancel_lru_locks mdc
7945         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7946                 error "S/gid is not dropped on MDS"
7947         rm -f $DIR/$tfile
7948 }
7949 run_test 72a "Test that remove suid works properly (bug5695) ===="
7950
7951 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7952         local perm
7953
7954         [ "$RUNAS_ID" = "$UID" ] &&
7955                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7956         [ "$RUNAS_ID" -eq 0 ] &&
7957                 skip_env "RUNAS_ID = 0 -- skipping"
7958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7959         # Check that testing environment is properly set up. Skip if not
7960         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7961                 skip_env "User $RUNAS_ID does not exist - skipping"
7962
7963         touch $DIR/${tfile}-f{g,u}
7964         test_mkdir $DIR/${tfile}-dg
7965         test_mkdir $DIR/${tfile}-du
7966         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7967         chmod g+s $DIR/${tfile}-{f,d}g
7968         chmod u+s $DIR/${tfile}-{f,d}u
7969         for perm in 777 2777 4777; do
7970                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7971                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7972                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7973                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7974         done
7975         true
7976 }
7977 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7978
7979 # bug 3462 - multiple simultaneous MDC requests
7980 test_73() {
7981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7982
7983         test_mkdir $DIR/d73-1
7984         test_mkdir $DIR/d73-2
7985         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7986         pid1=$!
7987
7988         lctl set_param fail_loc=0x80000129
7989         $MULTIOP $DIR/d73-1/f73-2 Oc &
7990         sleep 1
7991         lctl set_param fail_loc=0
7992
7993         $MULTIOP $DIR/d73-2/f73-3 Oc &
7994         pid3=$!
7995
7996         kill -USR1 $pid1
7997         wait $pid1 || return 1
7998
7999         sleep 25
8000
8001         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8002         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8003         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8004
8005         rm -rf $DIR/d73-*
8006 }
8007 run_test 73 "multiple MDC requests (should not deadlock)"
8008
8009 test_74a() { # bug 6149, 6184
8010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8011
8012         touch $DIR/f74a
8013         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8014         #
8015         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8016         # will spin in a tight reconnection loop
8017         $LCTL set_param fail_loc=0x8000030e
8018         # get any lock that won't be difficult - lookup works.
8019         ls $DIR/f74a
8020         $LCTL set_param fail_loc=0
8021         rm -f $DIR/f74a
8022         true
8023 }
8024 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8025
8026 test_74b() { # bug 13310
8027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8028
8029         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8030         #
8031         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8032         # will spin in a tight reconnection loop
8033         $LCTL set_param fail_loc=0x8000030e
8034         # get a "difficult" lock
8035         touch $DIR/f74b
8036         $LCTL set_param fail_loc=0
8037         rm -f $DIR/f74b
8038         true
8039 }
8040 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8041
8042 test_74c() {
8043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8044
8045         #define OBD_FAIL_LDLM_NEW_LOCK
8046         $LCTL set_param fail_loc=0x319
8047         touch $DIR/$tfile && error "touch successful"
8048         $LCTL set_param fail_loc=0
8049         true
8050 }
8051 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8052
8053 num_inodes() {
8054         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8055 }
8056
8057 test_76() { # Now for bug 20433, added originally in bug 1443
8058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8059
8060         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8061
8062         cancel_lru_locks osc
8063         BEFORE_INODES=$(num_inodes)
8064         echo "before inodes: $BEFORE_INODES"
8065         local COUNT=1000
8066         [ "$SLOW" = "no" ] && COUNT=100
8067         for i in $(seq $COUNT); do
8068                 touch $DIR/$tfile
8069                 rm -f $DIR/$tfile
8070         done
8071         cancel_lru_locks osc
8072         AFTER_INODES=$(num_inodes)
8073         echo "after inodes: $AFTER_INODES"
8074         local wait=0
8075         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
8076                 sleep 2
8077                 AFTER_INODES=$(num_inodes)
8078                 wait=$((wait+2))
8079                 echo "wait $wait seconds inodes: $AFTER_INODES"
8080                 if [ $wait -gt 30 ]; then
8081                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
8082                 fi
8083         done
8084 }
8085 run_test 76 "confirm clients recycle inodes properly ===="
8086
8087
8088 export ORIG_CSUM=""
8089 set_checksums()
8090 {
8091         # Note: in sptlrpc modes which enable its own bulk checksum, the
8092         # original crc32_le bulk checksum will be automatically disabled,
8093         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8094         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8095         # In this case set_checksums() will not be no-op, because sptlrpc
8096         # bulk checksum will be enabled all through the test.
8097
8098         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8099         lctl set_param -n osc.*.checksums $1
8100         return 0
8101 }
8102
8103 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8104                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8105 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8106                              tr -d [] | head -n1)}
8107 set_checksum_type()
8108 {
8109         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8110         rc=$?
8111         log "set checksum type to $1, rc = $rc"
8112         return $rc
8113 }
8114
8115 get_osc_checksum_type()
8116 {
8117         # arugment 1: OST name, like OST0000
8118         ost=$1
8119         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8120                         sed 's/.*\[\(.*\)\].*/\1/g')
8121         rc=$?
8122         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8123         echo $checksum_type
8124 }
8125
8126 F77_TMP=$TMP/f77-temp
8127 F77SZ=8
8128 setup_f77() {
8129         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8130                 error "error writing to $F77_TMP"
8131 }
8132
8133 test_77a() { # bug 10889
8134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8135         $GSS && skip_env "could not run with gss"
8136
8137         [ ! -f $F77_TMP ] && setup_f77
8138         set_checksums 1
8139         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8140         set_checksums 0
8141         rm -f $DIR/$tfile
8142 }
8143 run_test 77a "normal checksum read/write operation"
8144
8145 test_77b() { # bug 10889
8146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8147         $GSS && skip_env "could not run with gss"
8148
8149         [ ! -f $F77_TMP ] && setup_f77
8150         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8151         $LCTL set_param fail_loc=0x80000409
8152         set_checksums 1
8153
8154         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8155                 error "dd error: $?"
8156         $LCTL set_param fail_loc=0
8157
8158         for algo in $CKSUM_TYPES; do
8159                 cancel_lru_locks osc
8160                 set_checksum_type $algo
8161                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8162                 $LCTL set_param fail_loc=0x80000408
8163                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8164                 $LCTL set_param fail_loc=0
8165         done
8166         set_checksums 0
8167         set_checksum_type $ORIG_CSUM_TYPE
8168         rm -f $DIR/$tfile
8169 }
8170 run_test 77b "checksum error on client write, read"
8171
8172 cleanup_77c() {
8173         trap 0
8174         set_checksums 0
8175         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8176         $check_ost &&
8177                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8178         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8179         $check_ost && [ -n "$ost_file_prefix" ] &&
8180                 do_facet ost1 rm -f ${ost_file_prefix}\*
8181 }
8182
8183 test_77c() {
8184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8185         $GSS && skip_env "could not run with gss"
8186         remote_ost_nodsh && skip "remote OST with nodsh"
8187
8188         local bad1
8189         local osc_file_prefix
8190         local osc_file
8191         local check_ost=false
8192         local ost_file_prefix
8193         local ost_file
8194         local orig_cksum
8195         local dump_cksum
8196         local fid
8197
8198         # ensure corruption will occur on first OSS/OST
8199         $LFS setstripe -i 0 $DIR/$tfile
8200
8201         [ ! -f $F77_TMP ] && setup_f77
8202         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8203                 error "dd write error: $?"
8204         fid=$($LFS path2fid $DIR/$tfile)
8205
8206         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8207         then
8208                 check_ost=true
8209                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8210                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8211         else
8212                 echo "OSS do not support bulk pages dump upon error"
8213         fi
8214
8215         osc_file_prefix=$($LCTL get_param -n debug_path)
8216         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8217
8218         trap cleanup_77c EXIT
8219
8220         set_checksums 1
8221         # enable bulk pages dump upon error on Client
8222         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8223         # enable bulk pages dump upon error on OSS
8224         $check_ost &&
8225                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8226
8227         # flush Client cache to allow next read to reach OSS
8228         cancel_lru_locks osc
8229
8230         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8231         $LCTL set_param fail_loc=0x80000408
8232         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8233         $LCTL set_param fail_loc=0
8234
8235         rm -f $DIR/$tfile
8236
8237         # check cksum dump on Client
8238         osc_file=$(ls ${osc_file_prefix}*)
8239         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8240         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8241         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8242         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8243         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8244                      cksum)
8245         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8246         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8247                 error "dump content does not match on Client"
8248
8249         $check_ost || skip "No need to check cksum dump on OSS"
8250
8251         # check cksum dump on OSS
8252         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8253         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8254         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8255         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8256         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8257                 error "dump content does not match on OSS"
8258
8259         cleanup_77c
8260 }
8261 run_test 77c "checksum error on client read with debug"
8262
8263 test_77d() { # bug 10889
8264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8265         $GSS && skip_env "could not run with gss"
8266
8267         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8268         $LCTL set_param fail_loc=0x80000409
8269         set_checksums 1
8270         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8271                 error "direct write: rc=$?"
8272         $LCTL set_param fail_loc=0
8273         set_checksums 0
8274
8275         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8276         $LCTL set_param fail_loc=0x80000408
8277         set_checksums 1
8278         cancel_lru_locks osc
8279         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8280                 error "direct read: rc=$?"
8281         $LCTL set_param fail_loc=0
8282         set_checksums 0
8283 }
8284 run_test 77d "checksum error on OST direct write, read"
8285
8286 test_77f() { # bug 10889
8287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8288         $GSS && skip_env "could not run with gss"
8289
8290         set_checksums 1
8291         for algo in $CKSUM_TYPES; do
8292                 cancel_lru_locks osc
8293                 set_checksum_type $algo
8294                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8295                 $LCTL set_param fail_loc=0x409
8296                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8297                         error "direct write succeeded"
8298                 $LCTL set_param fail_loc=0
8299         done
8300         set_checksum_type $ORIG_CSUM_TYPE
8301         set_checksums 0
8302 }
8303 run_test 77f "repeat checksum error on write (expect error)"
8304
8305 test_77g() { # bug 10889
8306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8307         $GSS && skip_env "could not run with gss"
8308         remote_ost_nodsh && skip "remote OST with nodsh"
8309
8310         [ ! -f $F77_TMP ] && setup_f77
8311
8312         local file=$DIR/$tfile
8313         stack_trap "rm -f $file" EXIT
8314
8315         $LFS setstripe -c 1 -i 0 $file
8316         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8317         do_facet ost1 lctl set_param fail_loc=0x8000021a
8318         set_checksums 1
8319         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8320                 error "write error: rc=$?"
8321         do_facet ost1 lctl set_param fail_loc=0
8322         set_checksums 0
8323
8324         cancel_lru_locks osc
8325         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8326         do_facet ost1 lctl set_param fail_loc=0x8000021b
8327         set_checksums 1
8328         cmp $F77_TMP $file || error "file compare failed"
8329         do_facet ost1 lctl set_param fail_loc=0
8330         set_checksums 0
8331 }
8332 run_test 77g "checksum error on OST write, read"
8333
8334 test_77k() { # LU-10906
8335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8336         $GSS && skip_env "could not run with gss"
8337
8338         local cksum_param="osc.$FSNAME*.checksums"
8339         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8340         local checksum
8341         local i
8342
8343         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8344         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
8345         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
8346                 EXIT
8347
8348         for i in 0 1; do
8349                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8350                         error "failed to set checksum=$i on MGS"
8351                 wait_update $HOSTNAME "$get_checksum" $i
8352                 #remount
8353                 echo "remount client, checksum should be $i"
8354                 remount_client $MOUNT || error "failed to remount client"
8355                 checksum=$(eval $get_checksum)
8356                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8357         done
8358         # remove persistent param to avoid races with checksum mountopt below
8359         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8360                 error "failed to delete checksum on MGS"
8361
8362         for opt in "checksum" "nochecksum"; do
8363                 #remount with mount option
8364                 echo "remount client with option $opt, checksum should be $i"
8365                 umount_client $MOUNT || error "failed to umount client"
8366                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8367                         error "failed to mount client with option '$opt'"
8368                 checksum=$(eval $get_checksum)
8369                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8370                 i=$((i - 1))
8371         done
8372
8373         remount_client $MOUNT || error "failed to remount client"
8374 }
8375 run_test 77k "enable/disable checksum correctly"
8376
8377 test_77l() {
8378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8379         $GSS && skip_env "could not run with gss"
8380
8381         set_checksums 1
8382         stack_trap "set_checksums $ORIG_CSUM" EXIT
8383         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8384
8385         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8386
8387         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8388         for algo in $CKSUM_TYPES; do
8389                 set_checksum_type $algo || error "fail to set checksum type $algo"
8390                 osc_algo=$(get_osc_checksum_type OST0000)
8391                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8392
8393                 # no locks, no reqs to let the connection idle
8394                 cancel_lru_locks osc
8395                 lru_resize_disable osc
8396                 wait_osc_import_state client ost1 IDLE
8397
8398                 # ensure ost1 is connected
8399                 stat $DIR/$tfile >/dev/null || error "can't stat"
8400                 wait_osc_import_state client ost1 FULL
8401
8402                 osc_algo=$(get_osc_checksum_type OST0000)
8403                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8404         done
8405         return 0
8406 }
8407 run_test 77l "preferred checksum type is remembered after reconnected"
8408
8409 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8410 rm -f $F77_TMP
8411 unset F77_TMP
8412
8413 cleanup_test_78() {
8414         trap 0
8415         rm -f $DIR/$tfile
8416 }
8417
8418 test_78() { # bug 10901
8419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8420         remote_ost || skip_env "local OST"
8421
8422         NSEQ=5
8423         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8424         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8425         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8426         echo "MemTotal: $MEMTOTAL"
8427
8428         # reserve 256MB of memory for the kernel and other running processes,
8429         # and then take 1/2 of the remaining memory for the read/write buffers.
8430         if [ $MEMTOTAL -gt 512 ] ;then
8431                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8432         else
8433                 # for those poor memory-starved high-end clusters...
8434                 MEMTOTAL=$((MEMTOTAL / 2))
8435         fi
8436         echo "Mem to use for directio: $MEMTOTAL"
8437
8438         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8439         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8440         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8441         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8442                 head -n1)
8443         echo "Smallest OST: $SMALLESTOST"
8444         [[ $SMALLESTOST -lt 10240 ]] &&
8445                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8446
8447         trap cleanup_test_78 EXIT
8448
8449         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8450                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8451
8452         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8453         echo "File size: $F78SIZE"
8454         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8455         for i in $(seq 1 $NSEQ); do
8456                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8457                 echo directIO rdwr round $i of $NSEQ
8458                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8459         done
8460
8461         cleanup_test_78
8462 }
8463 run_test 78 "handle large O_DIRECT writes correctly ============"
8464
8465 test_79() { # bug 12743
8466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8467
8468         wait_delete_completed
8469
8470         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8471         BKFREE=$(calc_osc_kbytes kbytesfree)
8472         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8473
8474         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8475         DFTOTAL=`echo $STRING | cut -d, -f1`
8476         DFUSED=`echo $STRING  | cut -d, -f2`
8477         DFAVAIL=`echo $STRING | cut -d, -f3`
8478         DFFREE=$(($DFTOTAL - $DFUSED))
8479
8480         ALLOWANCE=$((64 * $OSTCOUNT))
8481
8482         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8483            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8484                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8485         fi
8486         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8487            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8488                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8489         fi
8490         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8491            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8492                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8493         fi
8494 }
8495 run_test 79 "df report consistency check ======================="
8496
8497 test_80() { # bug 10718
8498         remote_ost_nodsh && skip "remote OST with nodsh"
8499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8500
8501         # relax strong synchronous semantics for slow backends like ZFS
8502         local soc="obdfilter.*.sync_on_lock_cancel"
8503         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8504         local hosts=
8505         if [ "$soc_old" != "never" ] &&
8506                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8507                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8508                                 facet_active_host $host; done | sort -u)
8509                         do_nodes $hosts lctl set_param $soc=never
8510         fi
8511
8512         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8513         sync; sleep 1; sync
8514         local BEFORE=`date +%s`
8515         cancel_lru_locks osc
8516         local AFTER=`date +%s`
8517         local DIFF=$((AFTER-BEFORE))
8518         if [ $DIFF -gt 1 ] ; then
8519                 error "elapsed for 1M@1T = $DIFF"
8520         fi
8521
8522         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8523
8524         rm -f $DIR/$tfile
8525 }
8526 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8527
8528 test_81a() { # LU-456
8529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8530         remote_ost_nodsh && skip "remote OST with nodsh"
8531
8532         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8533         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8534         do_facet ost1 lctl set_param fail_loc=0x80000228
8535
8536         # write should trigger a retry and success
8537         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8538         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8539         RC=$?
8540         if [ $RC -ne 0 ] ; then
8541                 error "write should success, but failed for $RC"
8542         fi
8543 }
8544 run_test 81a "OST should retry write when get -ENOSPC ==============="
8545
8546 test_81b() { # LU-456
8547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8548         remote_ost_nodsh && skip "remote OST with nodsh"
8549
8550         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8551         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8552         do_facet ost1 lctl set_param fail_loc=0x228
8553
8554         # write should retry several times and return -ENOSPC finally
8555         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8556         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8557         RC=$?
8558         ENOSPC=28
8559         if [ $RC -ne $ENOSPC ] ; then
8560                 error "dd should fail for -ENOSPC, but succeed."
8561         fi
8562 }
8563 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8564
8565 test_82() { # LU-1031
8566         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8567         local gid1=14091995
8568         local gid2=16022000
8569
8570         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8571         local MULTIPID1=$!
8572         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8573         local MULTIPID2=$!
8574         kill -USR1 $MULTIPID2
8575         sleep 2
8576         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8577                 error "First grouplock does not block second one"
8578         else
8579                 echo "Second grouplock blocks first one"
8580         fi
8581         kill -USR1 $MULTIPID1
8582         wait $MULTIPID1
8583         wait $MULTIPID2
8584 }
8585 run_test 82 "Basic grouplock test"
8586
8587 test_99() {
8588         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8589
8590         test_mkdir $DIR/$tdir.cvsroot
8591         chown $RUNAS_ID $DIR/$tdir.cvsroot
8592
8593         cd $TMP
8594         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8595
8596         cd /etc/init.d
8597         # some versions of cvs import exit(1) when asked to import links or
8598         # files they can't read.  ignore those files.
8599         local toignore=$(find . -type l -printf '-I %f\n' -o \
8600                          ! -perm /4 -printf '-I %f\n')
8601         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8602                 $tdir.reposname vtag rtag
8603
8604         cd $DIR
8605         test_mkdir $DIR/$tdir.reposname
8606         chown $RUNAS_ID $DIR/$tdir.reposname
8607         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8608
8609         cd $DIR/$tdir.reposname
8610         $RUNAS touch foo99
8611         $RUNAS cvs add -m 'addmsg' foo99
8612         $RUNAS cvs update
8613         $RUNAS cvs commit -m 'nomsg' foo99
8614         rm -fr $DIR/$tdir.cvsroot
8615 }
8616 run_test 99 "cvs strange file/directory operations"
8617
8618 test_100() {
8619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8620         [[ "$NETTYPE" =~ tcp ]] ||
8621                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8622         remote_ost_nodsh && skip "remote OST with nodsh"
8623         remote_mds_nodsh && skip "remote MDS with nodsh"
8624         remote_servers ||
8625                 skip "useless for local single node setup"
8626
8627         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8628                 [ "$PROT" != "tcp" ] && continue
8629                 RPORT=$(echo $REMOTE | cut -d: -f2)
8630                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8631
8632                 rc=0
8633                 LPORT=`echo $LOCAL | cut -d: -f2`
8634                 if [ $LPORT -ge 1024 ]; then
8635                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8636                         netstat -tna
8637                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8638                 fi
8639         done
8640         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8641 }
8642 run_test 100 "check local port using privileged port ==========="
8643
8644 function get_named_value()
8645 {
8646     local tag
8647
8648     tag=$1
8649     while read ;do
8650         line=$REPLY
8651         case $line in
8652         $tag*)
8653             echo $line | sed "s/^$tag[ ]*//"
8654             break
8655             ;;
8656         esac
8657     done
8658 }
8659
8660 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8661                    awk '/^max_cached_mb/ { print $2 }')
8662
8663 cleanup_101a() {
8664         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8665         trap 0
8666 }
8667
8668 test_101a() {
8669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8670         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
8671
8672         local s
8673         local discard
8674         local nreads=10000
8675         local cache_limit=32
8676
8677         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8678         trap cleanup_101a EXIT
8679         $LCTL set_param -n llite.*.read_ahead_stats 0
8680         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8681
8682         #
8683         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8684         #
8685         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8686         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8687
8688         discard=0
8689         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8690                 get_named_value 'read but discarded' | cut -d" " -f1); do
8691                         discard=$(($discard + $s))
8692         done
8693         cleanup_101a
8694
8695         if [[ $(($discard * 10)) -gt $nreads ]]; then
8696                 $LCTL get_param osc.*-osc*.rpc_stats
8697                 $LCTL get_param llite.*.read_ahead_stats
8698                 error "too many ($discard) discarded pages"
8699         fi
8700         rm -f $DIR/$tfile || true
8701 }
8702 run_test 101a "check read-ahead for random reads"
8703
8704 setup_test101bc() {
8705         test_mkdir $DIR/$tdir
8706         local ssize=$1
8707         local FILE_LENGTH=$2
8708         STRIPE_OFFSET=0
8709
8710         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8711
8712         local list=$(comma_list $(osts_nodes))
8713         set_osd_param $list '' read_cache_enable 0
8714         set_osd_param $list '' writethrough_cache_enable 0
8715
8716         trap cleanup_test101bc EXIT
8717         # prepare the read-ahead file
8718         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8719
8720         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8721                                 count=$FILE_SIZE_MB 2> /dev/null
8722
8723 }
8724
8725 cleanup_test101bc() {
8726         trap 0
8727         rm -rf $DIR/$tdir
8728         rm -f $DIR/$tfile
8729
8730         local list=$(comma_list $(osts_nodes))
8731         set_osd_param $list '' read_cache_enable 1
8732         set_osd_param $list '' writethrough_cache_enable 1
8733 }
8734
8735 calc_total() {
8736         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8737 }
8738
8739 ra_check_101() {
8740         local READ_SIZE=$1
8741         local STRIPE_SIZE=$2
8742         local FILE_LENGTH=$3
8743         local RA_INC=1048576
8744         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8745         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8746                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8747         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8748                         get_named_value 'read but discarded' |
8749                         cut -d" " -f1 | calc_total)
8750         if [[ $DISCARD -gt $discard_limit ]]; then
8751                 $LCTL get_param llite.*.read_ahead_stats
8752                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8753         else
8754                 echo "Read-ahead success for size ${READ_SIZE}"
8755         fi
8756 }
8757
8758 test_101b() {
8759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8760         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8761
8762         local STRIPE_SIZE=1048576
8763         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8764
8765         if [ $SLOW == "yes" ]; then
8766                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8767         else
8768                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8769         fi
8770
8771         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8772
8773         # prepare the read-ahead file
8774         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8775         cancel_lru_locks osc
8776         for BIDX in 2 4 8 16 32 64 128 256
8777         do
8778                 local BSIZE=$((BIDX*4096))
8779                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8780                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8781                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8782                 $LCTL set_param -n llite.*.read_ahead_stats 0
8783                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8784                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8785                 cancel_lru_locks osc
8786                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8787         done
8788         cleanup_test101bc
8789         true
8790 }
8791 run_test 101b "check stride-io mode read-ahead ================="
8792
8793 test_101c() {
8794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8795
8796         local STRIPE_SIZE=1048576
8797         local FILE_LENGTH=$((STRIPE_SIZE*100))
8798         local nreads=10000
8799         local rsize=65536
8800         local osc_rpc_stats
8801
8802         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8803
8804         cancel_lru_locks osc
8805         $LCTL set_param osc.*.rpc_stats 0
8806         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8807         $LCTL get_param osc.*.rpc_stats
8808         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8809                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8810                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8811                 local size
8812
8813                 if [ $lines -le 20 ]; then
8814                         echo "continue debug"
8815                         continue
8816                 fi
8817                 for size in 1 2 4 8; do
8818                         local rpc=$(echo "$stats" |
8819                                     awk '($1 == "'$size':") {print $2; exit; }')
8820                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8821                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8822                 done
8823                 echo "$osc_rpc_stats check passed!"
8824         done
8825         cleanup_test101bc
8826         true
8827 }
8828 run_test 101c "check stripe_size aligned read-ahead ================="
8829
8830 set_read_ahead() {
8831         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8832         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8833 }
8834
8835 test_101d() {
8836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8837
8838         local file=$DIR/$tfile
8839         local sz_MB=${FILESIZE_101d:-500}
8840         local ra_MB=${READAHEAD_MB:-40}
8841
8842         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8843         [ $free_MB -lt $sz_MB ] &&
8844                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8845
8846         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8847         $LFS setstripe -c -1 $file || error "setstripe failed"
8848
8849         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8850         echo Cancel LRU locks on lustre client to flush the client cache
8851         cancel_lru_locks osc
8852
8853         echo Disable read-ahead
8854         local old_READAHEAD=$(set_read_ahead 0)
8855
8856         echo Reading the test file $file with read-ahead disabled
8857         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8858
8859         echo Cancel LRU locks on lustre client to flush the client cache
8860         cancel_lru_locks osc
8861         echo Enable read-ahead with ${ra_MB}MB
8862         set_read_ahead $ra_MB
8863
8864         echo Reading the test file $file with read-ahead enabled
8865         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8866
8867         echo "read-ahead disabled time read $raOFF"
8868         echo "read-ahead enabled  time read $raON"
8869
8870         set_read_ahead $old_READAHEAD
8871         rm -f $file
8872         wait_delete_completed
8873
8874         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8875                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8876 }
8877 run_test 101d "file read with and without read-ahead enabled"
8878
8879 test_101e() {
8880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8881
8882         local file=$DIR/$tfile
8883         local size_KB=500  #KB
8884         local count=100
8885         local bsize=1024
8886
8887         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8888         local need_KB=$((count * size_KB))
8889         [[ $free_KB -le $need_KB ]] &&
8890                 skip_env "Need free space $need_KB, have $free_KB"
8891
8892         echo "Creating $count ${size_KB}K test files"
8893         for ((i = 0; i < $count; i++)); do
8894                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8895         done
8896
8897         echo "Cancel LRU locks on lustre client to flush the client cache"
8898         cancel_lru_locks $OSC
8899
8900         echo "Reset readahead stats"
8901         $LCTL set_param -n llite.*.read_ahead_stats 0
8902
8903         for ((i = 0; i < $count; i++)); do
8904                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8905         done
8906
8907         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8908                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8909
8910         for ((i = 0; i < $count; i++)); do
8911                 rm -rf $file.$i 2>/dev/null
8912         done
8913
8914         #10000 means 20% reads are missing in readahead
8915         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8916 }
8917 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8918
8919 test_101f() {
8920         which iozone || skip_env "no iozone installed"
8921
8922         local old_debug=$($LCTL get_param debug)
8923         old_debug=${old_debug#*=}
8924         $LCTL set_param debug="reada mmap"
8925
8926         # create a test file
8927         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8928
8929         echo Cancel LRU locks on lustre client to flush the client cache
8930         cancel_lru_locks osc
8931
8932         echo Reset readahead stats
8933         $LCTL set_param -n llite.*.read_ahead_stats 0
8934
8935         echo mmap read the file with small block size
8936         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8937                 > /dev/null 2>&1
8938
8939         echo checking missing pages
8940         $LCTL get_param llite.*.read_ahead_stats
8941         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8942                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8943
8944         $LCTL set_param debug="$old_debug"
8945         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8946         rm -f $DIR/$tfile
8947 }
8948 run_test 101f "check mmap read performance"
8949
8950 test_101g_brw_size_test() {
8951         local mb=$1
8952         local pages=$((mb * 1048576 / PAGE_SIZE))
8953         local file=$DIR/$tfile
8954
8955         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8956                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8957         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8958                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8959                         return 2
8960         done
8961
8962         stack_trap "rm -f $file" EXIT
8963         $LCTL set_param -n osc.*.rpc_stats=0
8964
8965         # 10 RPCs should be enough for the test
8966         local count=10
8967         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8968                 { error "dd write ${mb} MB blocks failed"; return 3; }
8969         cancel_lru_locks osc
8970         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8971                 { error "dd write ${mb} MB blocks failed"; return 4; }
8972
8973         # calculate number of full-sized read and write RPCs
8974         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8975                 sed -n '/pages per rpc/,/^$/p' |
8976                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8977                 END { print reads,writes }'))
8978         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8979                 return 5
8980         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8981                 return 6
8982
8983         return 0
8984 }
8985
8986 test_101g() {
8987         remote_ost_nodsh && skip "remote OST with nodsh"
8988
8989         local rpcs
8990         local osts=$(get_facets OST)
8991         local list=$(comma_list $(osts_nodes))
8992         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8993         local brw_size="obdfilter.*.brw_size"
8994
8995         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8996
8997         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8998
8999         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9000                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9001                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9002            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9003                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9004                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9005
9006                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9007                         suffix="M"
9008
9009                 if [[ $orig_mb -lt 16 ]]; then
9010                         save_lustre_params $osts "$brw_size" > $p
9011                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9012                                 error "set 16MB RPC size failed"
9013
9014                         echo "remount client to enable new RPC size"
9015                         remount_client $MOUNT || error "remount_client failed"
9016                 fi
9017
9018                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9019                 # should be able to set brw_size=12, but no rpc_stats for that
9020                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9021         fi
9022
9023         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9024
9025         if [[ $orig_mb -lt 16 ]]; then
9026                 restore_lustre_params < $p
9027                 remount_client $MOUNT || error "remount_client restore failed"
9028         fi
9029
9030         rm -f $p $DIR/$tfile
9031 }
9032 run_test 101g "Big bulk(4/16 MiB) readahead"
9033
9034 test_101h() {
9035         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9036
9037         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9038                 error "dd 70M file failed"
9039         echo Cancel LRU locks on lustre client to flush the client cache
9040         cancel_lru_locks osc
9041
9042         echo "Reset readahead stats"
9043         $LCTL set_param -n llite.*.read_ahead_stats 0
9044
9045         echo "Read 10M of data but cross 64M bundary"
9046         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9047         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9048                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9049         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9050         rm -f $p $DIR/$tfile
9051 }
9052 run_test 101h "Readahead should cover current read window"
9053
9054 setup_test102() {
9055         test_mkdir $DIR/$tdir
9056         chown $RUNAS_ID $DIR/$tdir
9057         STRIPE_SIZE=65536
9058         STRIPE_OFFSET=1
9059         STRIPE_COUNT=$OSTCOUNT
9060         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9061
9062         trap cleanup_test102 EXIT
9063         cd $DIR
9064         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9065         cd $DIR/$tdir
9066         for num in 1 2 3 4; do
9067                 for count in $(seq 1 $STRIPE_COUNT); do
9068                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9069                                 local size=`expr $STRIPE_SIZE \* $num`
9070                                 local file=file"$num-$idx-$count"
9071                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9072                         done
9073                 done
9074         done
9075
9076         cd $DIR
9077         $1 tar cf $TMP/f102.tar $tdir --xattrs
9078 }
9079
9080 cleanup_test102() {
9081         trap 0
9082         rm -f $TMP/f102.tar
9083         rm -rf $DIR/d0.sanity/d102
9084 }
9085
9086 test_102a() {
9087         [ "$UID" != 0 ] && skip "must run as root"
9088         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9089                 skip_env "must have user_xattr"
9090
9091         [ -z "$(which setfattr 2>/dev/null)" ] &&
9092                 skip_env "could not find setfattr"
9093
9094         local testfile=$DIR/$tfile
9095
9096         touch $testfile
9097         echo "set/get xattr..."
9098         setfattr -n trusted.name1 -v value1 $testfile ||
9099                 error "setfattr -n trusted.name1=value1 $testfile failed"
9100         getfattr -n trusted.name1 $testfile 2> /dev/null |
9101           grep "trusted.name1=.value1" ||
9102                 error "$testfile missing trusted.name1=value1"
9103
9104         setfattr -n user.author1 -v author1 $testfile ||
9105                 error "setfattr -n user.author1=author1 $testfile failed"
9106         getfattr -n user.author1 $testfile 2> /dev/null |
9107           grep "user.author1=.author1" ||
9108                 error "$testfile missing trusted.author1=author1"
9109
9110         echo "listxattr..."
9111         setfattr -n trusted.name2 -v value2 $testfile ||
9112                 error "$testfile unable to set trusted.name2"
9113         setfattr -n trusted.name3 -v value3 $testfile ||
9114                 error "$testfile unable to set trusted.name3"
9115         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9116             grep "trusted.name" | wc -l) -eq 3 ] ||
9117                 error "$testfile missing 3 trusted.name xattrs"
9118
9119         setfattr -n user.author2 -v author2 $testfile ||
9120                 error "$testfile unable to set user.author2"
9121         setfattr -n user.author3 -v author3 $testfile ||
9122                 error "$testfile unable to set user.author3"
9123         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9124             grep "user.author" | wc -l) -eq 3 ] ||
9125                 error "$testfile missing 3 user.author xattrs"
9126
9127         echo "remove xattr..."
9128         setfattr -x trusted.name1 $testfile ||
9129                 error "$testfile error deleting trusted.name1"
9130         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9131                 error "$testfile did not delete trusted.name1 xattr"
9132
9133         setfattr -x user.author1 $testfile ||
9134                 error "$testfile error deleting user.author1"
9135         echo "set lustre special xattr ..."
9136         $LFS setstripe -c1 $testfile
9137         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9138                 awk -F "=" '/trusted.lov/ { print $2 }' )
9139         setfattr -n "trusted.lov" -v $lovea $testfile ||
9140                 error "$testfile doesn't ignore setting trusted.lov again"
9141         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9142                 error "$testfile allow setting invalid trusted.lov"
9143         rm -f $testfile
9144 }
9145 run_test 102a "user xattr test =================================="
9146
9147 test_102b() {
9148         [ -z "$(which setfattr 2>/dev/null)" ] &&
9149                 skip_env "could not find setfattr"
9150         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9151
9152         # b10930: get/set/list trusted.lov xattr
9153         echo "get/set/list trusted.lov xattr ..."
9154         local testfile=$DIR/$tfile
9155         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9156                 error "setstripe failed"
9157         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
9158                 error "getstripe failed"
9159         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
9160                 error "can't get trusted.lov from $testfile"
9161
9162         local testfile2=${testfile}2
9163         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
9164                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
9165
9166         $MCREATE $testfile2
9167         setfattr -n trusted.lov -v $value $testfile2
9168         local stripe_size=$($LFS getstripe -S $testfile2)
9169         local stripe_count=$($LFS getstripe -c $testfile2)
9170         [[ $stripe_size -eq 65536 ]] ||
9171                 error "stripe size $stripe_size != 65536"
9172         [[ $stripe_count -eq $STRIPECOUNT ]] ||
9173                 error "stripe count $stripe_count != $STRIPECOUNT"
9174         rm -f $DIR/$tfile
9175 }
9176 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
9177
9178 test_102c() {
9179         [ -z "$(which setfattr 2>/dev/null)" ] &&
9180                 skip_env "could not find setfattr"
9181         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9182
9183         # b10930: get/set/list lustre.lov xattr
9184         echo "get/set/list lustre.lov xattr ..."
9185         test_mkdir $DIR/$tdir
9186         chown $RUNAS_ID $DIR/$tdir
9187         local testfile=$DIR/$tdir/$tfile
9188         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9189                 error "setstripe failed"
9190         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9191                 error "getstripe failed"
9192         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9193         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9194
9195         local testfile2=${testfile}2
9196         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9197                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9198
9199         $RUNAS $MCREATE $testfile2
9200         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9201         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9202         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9203         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9204         [ $stripe_count -eq $STRIPECOUNT ] ||
9205                 error "stripe count $stripe_count != $STRIPECOUNT"
9206 }
9207 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9208
9209 compare_stripe_info1() {
9210         local stripe_index_all_zero=true
9211
9212         for num in 1 2 3 4; do
9213                 for count in $(seq 1 $STRIPE_COUNT); do
9214                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9215                                 local size=$((STRIPE_SIZE * num))
9216                                 local file=file"$num-$offset-$count"
9217                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9218                                 [[ $stripe_size -ne $size ]] &&
9219                                     error "$file: size $stripe_size != $size"
9220                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9221                                 # allow fewer stripes to be created, ORI-601
9222                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9223                                     error "$file: count $stripe_count != $count"
9224                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9225                                 [[ $stripe_index -ne 0 ]] &&
9226                                         stripe_index_all_zero=false
9227                         done
9228                 done
9229         done
9230         $stripe_index_all_zero &&
9231                 error "all files are being extracted starting from OST index 0"
9232         return 0
9233 }
9234
9235 have_xattrs_include() {
9236         tar --help | grep -q xattrs-include &&
9237                 echo --xattrs-include="lustre.*"
9238 }
9239
9240 test_102d() {
9241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9242         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9243
9244         XINC=$(have_xattrs_include)
9245         setup_test102
9246         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9247         cd $DIR/$tdir/$tdir
9248         compare_stripe_info1
9249 }
9250 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9251
9252 test_102f() {
9253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9254         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9255
9256         XINC=$(have_xattrs_include)
9257         setup_test102
9258         test_mkdir $DIR/$tdir.restore
9259         cd $DIR
9260         tar cf - --xattrs $tdir | tar xf - \
9261                 -C $DIR/$tdir.restore --xattrs $XINC
9262         cd $DIR/$tdir.restore/$tdir
9263         compare_stripe_info1
9264 }
9265 run_test 102f "tar copy files, not keep osts"
9266
9267 grow_xattr() {
9268         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9269                 skip "must have user_xattr"
9270         [ -z "$(which setfattr 2>/dev/null)" ] &&
9271                 skip_env "could not find setfattr"
9272         [ -z "$(which getfattr 2>/dev/null)" ] &&
9273                 skip_env "could not find getfattr"
9274
9275         local xsize=${1:-1024}  # in bytes
9276         local file=$DIR/$tfile
9277         local value="$(generate_string $xsize)"
9278         local xbig=trusted.big
9279         local toobig=$2
9280
9281         touch $file
9282         log "save $xbig on $file"
9283         if [ -z "$toobig" ]
9284         then
9285                 setfattr -n $xbig -v $value $file ||
9286                         error "saving $xbig on $file failed"
9287         else
9288                 setfattr -n $xbig -v $value $file &&
9289                         error "saving $xbig on $file succeeded"
9290                 return 0
9291         fi
9292
9293         local orig=$(get_xattr_value $xbig $file)
9294         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9295
9296         local xsml=trusted.sml
9297         log "save $xsml on $file"
9298         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9299
9300         local new=$(get_xattr_value $xbig $file)
9301         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9302
9303         log "grow $xsml on $file"
9304         setfattr -n $xsml -v "$value" $file ||
9305                 error "growing $xsml on $file failed"
9306
9307         new=$(get_xattr_value $xbig $file)
9308         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9309         log "$xbig still valid after growing $xsml"
9310
9311         rm -f $file
9312 }
9313
9314 test_102h() { # bug 15777
9315         grow_xattr 1024
9316 }
9317 run_test 102h "grow xattr from inside inode to external block"
9318
9319 test_102ha() {
9320         large_xattr_enabled || skip_env "ea_inode feature disabled"
9321
9322         echo "setting xattr of max xattr size: $(max_xattr_size)"
9323         grow_xattr $(max_xattr_size)
9324
9325         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9326         echo "This should fail:"
9327         grow_xattr $(($(max_xattr_size) + 10)) 1
9328 }
9329 run_test 102ha "grow xattr from inside inode to external inode"
9330
9331 test_102i() { # bug 17038
9332         [ -z "$(which getfattr 2>/dev/null)" ] &&
9333                 skip "could not find getfattr"
9334
9335         touch $DIR/$tfile
9336         ln -s $DIR/$tfile $DIR/${tfile}link
9337         getfattr -n trusted.lov $DIR/$tfile ||
9338                 error "lgetxattr on $DIR/$tfile failed"
9339         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9340                 grep -i "no such attr" ||
9341                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9342         rm -f $DIR/$tfile $DIR/${tfile}link
9343 }
9344 run_test 102i "lgetxattr test on symbolic link ============"
9345
9346 test_102j() {
9347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9348         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9349
9350         XINC=$(have_xattrs_include)
9351         setup_test102 "$RUNAS"
9352         chown $RUNAS_ID $DIR/$tdir
9353         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9354         cd $DIR/$tdir/$tdir
9355         compare_stripe_info1 "$RUNAS"
9356 }
9357 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9358
9359 test_102k() {
9360         [ -z "$(which setfattr 2>/dev/null)" ] &&
9361                 skip "could not find setfattr"
9362
9363         touch $DIR/$tfile
9364         # b22187 just check that does not crash for regular file.
9365         setfattr -n trusted.lov $DIR/$tfile
9366         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9367         local test_kdir=$DIR/$tdir
9368         test_mkdir $test_kdir
9369         local default_size=$($LFS getstripe -S $test_kdir)
9370         local default_count=$($LFS getstripe -c $test_kdir)
9371         local default_offset=$($LFS getstripe -i $test_kdir)
9372         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9373                 error 'dir setstripe failed'
9374         setfattr -n trusted.lov $test_kdir
9375         local stripe_size=$($LFS getstripe -S $test_kdir)
9376         local stripe_count=$($LFS getstripe -c $test_kdir)
9377         local stripe_offset=$($LFS getstripe -i $test_kdir)
9378         [ $stripe_size -eq $default_size ] ||
9379                 error "stripe size $stripe_size != $default_size"
9380         [ $stripe_count -eq $default_count ] ||
9381                 error "stripe count $stripe_count != $default_count"
9382         [ $stripe_offset -eq $default_offset ] ||
9383                 error "stripe offset $stripe_offset != $default_offset"
9384         rm -rf $DIR/$tfile $test_kdir
9385 }
9386 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
9387
9388 test_102l() {
9389         [ -z "$(which getfattr 2>/dev/null)" ] &&
9390                 skip "could not find getfattr"
9391
9392         # LU-532 trusted. xattr is invisible to non-root
9393         local testfile=$DIR/$tfile
9394
9395         touch $testfile
9396
9397         echo "listxattr as user..."
9398         chown $RUNAS_ID $testfile
9399         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
9400             grep -q "trusted" &&
9401                 error "$testfile trusted xattrs are user visible"
9402
9403         return 0;
9404 }
9405 run_test 102l "listxattr size test =================================="
9406
9407 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9408         local path=$DIR/$tfile
9409         touch $path
9410
9411         listxattr_size_check $path || error "listattr_size_check $path failed"
9412 }
9413 run_test 102m "Ensure listxattr fails on small bufffer ========"
9414
9415 cleanup_test102
9416
9417 getxattr() { # getxattr path name
9418         # Return the base64 encoding of the value of xattr name on path.
9419         local path=$1
9420         local name=$2
9421
9422         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9423         # file: $path
9424         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9425         #
9426         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9427
9428         getfattr --absolute-names --encoding=base64 --name=$name $path |
9429                 awk -F= -v name=$name '$1 == name {
9430                         print substr($0, index($0, "=") + 1);
9431         }'
9432 }
9433
9434 test_102n() { # LU-4101 mdt: protect internal xattrs
9435         [ -z "$(which setfattr 2>/dev/null)" ] &&
9436                 skip "could not find setfattr"
9437         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9438         then
9439                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9440         fi
9441
9442         local file0=$DIR/$tfile.0
9443         local file1=$DIR/$tfile.1
9444         local xattr0=$TMP/$tfile.0
9445         local xattr1=$TMP/$tfile.1
9446         local namelist="lov lma lmv link fid version som hsm"
9447         local name
9448         local value
9449
9450         rm -rf $file0 $file1 $xattr0 $xattr1
9451         touch $file0 $file1
9452
9453         # Get 'before' xattrs of $file1.
9454         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9455
9456         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9457                 namelist+=" lfsck_namespace"
9458         for name in $namelist; do
9459                 # Try to copy xattr from $file0 to $file1.
9460                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9461
9462                 setfattr --name=trusted.$name --value="$value" $file1 ||
9463                         error "setxattr 'trusted.$name' failed"
9464
9465                 # Try to set a garbage xattr.
9466                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9467
9468                 if [[ x$name == "xlov" ]]; then
9469                         setfattr --name=trusted.lov --value="$value" $file1 &&
9470                         error "setxattr invalid 'trusted.lov' success"
9471                 else
9472                         setfattr --name=trusted.$name --value="$value" $file1 ||
9473                                 error "setxattr invalid 'trusted.$name' failed"
9474                 fi
9475
9476                 # Try to remove the xattr from $file1. We don't care if this
9477                 # appears to succeed or fail, we just don't want there to be
9478                 # any changes or crashes.
9479                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9480         done
9481
9482         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9483         then
9484                 name="lfsck_ns"
9485                 # Try to copy xattr from $file0 to $file1.
9486                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9487
9488                 setfattr --name=trusted.$name --value="$value" $file1 ||
9489                         error "setxattr 'trusted.$name' failed"
9490
9491                 # Try to set a garbage xattr.
9492                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9493
9494                 setfattr --name=trusted.$name --value="$value" $file1 ||
9495                         error "setxattr 'trusted.$name' failed"
9496
9497                 # Try to remove the xattr from $file1. We don't care if this
9498                 # appears to succeed or fail, we just don't want there to be
9499                 # any changes or crashes.
9500                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9501         fi
9502
9503         # Get 'after' xattrs of file1.
9504         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9505
9506         if ! diff $xattr0 $xattr1; then
9507                 error "before and after xattrs of '$file1' differ"
9508         fi
9509
9510         rm -rf $file0 $file1 $xattr0 $xattr1
9511
9512         return 0
9513 }
9514 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9515
9516 test_102p() { # LU-4703 setxattr did not check ownership
9517         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9518                 skip "MDS needs to be at least 2.5.56"
9519
9520         local testfile=$DIR/$tfile
9521
9522         touch $testfile
9523
9524         echo "setfacl as user..."
9525         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9526         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9527
9528         echo "setfattr as user..."
9529         setfacl -m "u:$RUNAS_ID:---" $testfile
9530         $RUNAS setfattr -x system.posix_acl_access $testfile
9531         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9532 }
9533 run_test 102p "check setxattr(2) correctly fails without permission"
9534
9535 test_102q() {
9536         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9537                 skip "MDS needs to be at least 2.6.92"
9538
9539         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9540 }
9541 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9542
9543 test_102r() {
9544         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9545                 skip "MDS needs to be at least 2.6.93"
9546
9547         touch $DIR/$tfile || error "touch"
9548         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9549         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9550         rm $DIR/$tfile || error "rm"
9551
9552         #normal directory
9553         mkdir -p $DIR/$tdir || error "mkdir"
9554         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9555         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9556         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9557                 error "$testfile error deleting user.author1"
9558         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9559                 grep "user.$(basename $tdir)" &&
9560                 error "$tdir did not delete user.$(basename $tdir)"
9561         rmdir $DIR/$tdir || error "rmdir"
9562
9563         #striped directory
9564         test_mkdir $DIR/$tdir
9565         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9566         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9567         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9568                 error "$testfile error deleting user.author1"
9569         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9570                 grep "user.$(basename $tdir)" &&
9571                 error "$tdir did not delete user.$(basename $tdir)"
9572         rmdir $DIR/$tdir || error "rm striped dir"
9573 }
9574 run_test 102r "set EAs with empty values"
9575
9576 test_102s() {
9577         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9578                 skip "MDS needs to be at least 2.11.52"
9579
9580         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9581
9582         save_lustre_params client "llite.*.xattr_cache" > $save
9583
9584         for cache in 0 1; do
9585                 lctl set_param llite.*.xattr_cache=$cache
9586
9587                 rm -f $DIR/$tfile
9588                 touch $DIR/$tfile || error "touch"
9589                 for prefix in lustre security system trusted user; do
9590                         # Note getxattr() may fail with 'Operation not
9591                         # supported' or 'No such attribute' depending
9592                         # on prefix and cache.
9593                         getfattr -n $prefix.n102s $DIR/$tfile &&
9594                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9595                 done
9596         done
9597
9598         restore_lustre_params < $save
9599 }
9600 run_test 102s "getting nonexistent xattrs should fail"
9601
9602 test_102t() {
9603         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9604                 skip "MDS needs to be at least 2.11.52"
9605
9606         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9607
9608         save_lustre_params client "llite.*.xattr_cache" > $save
9609
9610         for cache in 0 1; do
9611                 lctl set_param llite.*.xattr_cache=$cache
9612
9613                 for buf_size in 0 256; do
9614                         rm -f $DIR/$tfile
9615                         touch $DIR/$tfile || error "touch"
9616                         setfattr -n user.multiop $DIR/$tfile
9617                         $MULTIOP $DIR/$tfile oa$buf_size ||
9618                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9619                 done
9620         done
9621
9622         restore_lustre_params < $save
9623 }
9624 run_test 102t "zero length xattr values handled correctly"
9625
9626 run_acl_subtest()
9627 {
9628     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9629     return $?
9630 }
9631
9632 test_103a() {
9633         [ "$UID" != 0 ] && skip "must run as root"
9634         $GSS && skip_env "could not run under gss"
9635         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9636                 skip_env "must have acl enabled"
9637         [ -z "$(which setfacl 2>/dev/null)" ] &&
9638                 skip_env "could not find setfacl"
9639         remote_mds_nodsh && skip "remote MDS with nodsh"
9640
9641         gpasswd -a daemon bin                           # LU-5641
9642         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9643
9644         declare -a identity_old
9645
9646         for num in $(seq $MDSCOUNT); do
9647                 switch_identity $num true || identity_old[$num]=$?
9648         done
9649
9650         SAVE_UMASK=$(umask)
9651         umask 0022
9652         mkdir -p $DIR/$tdir
9653         cd $DIR/$tdir
9654
9655         echo "performing cp ..."
9656         run_acl_subtest cp || error "run_acl_subtest cp failed"
9657         echo "performing getfacl-noacl..."
9658         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9659         echo "performing misc..."
9660         run_acl_subtest misc || error  "misc test failed"
9661         echo "performing permissions..."
9662         run_acl_subtest permissions || error "permissions failed"
9663         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9664         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9665                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9666                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9667         then
9668                 echo "performing permissions xattr..."
9669                 run_acl_subtest permissions_xattr ||
9670                         error "permissions_xattr failed"
9671         fi
9672         echo "performing setfacl..."
9673         run_acl_subtest setfacl || error  "setfacl test failed"
9674
9675         # inheritance test got from HP
9676         echo "performing inheritance..."
9677         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9678         chmod +x make-tree || error "chmod +x failed"
9679         run_acl_subtest inheritance || error "inheritance test failed"
9680         rm -f make-tree
9681
9682         echo "LU-974 ignore umask when acl is enabled..."
9683         run_acl_subtest 974 || error "LU-974 umask test failed"
9684         if [ $MDSCOUNT -ge 2 ]; then
9685                 run_acl_subtest 974_remote ||
9686                         error "LU-974 umask test failed under remote dir"
9687         fi
9688
9689         echo "LU-2561 newly created file is same size as directory..."
9690         if [ "$mds1_FSTYPE" != "zfs" ]; then
9691                 run_acl_subtest 2561 || error "LU-2561 test failed"
9692         else
9693                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9694         fi
9695
9696         run_acl_subtest 4924 || error "LU-4924 test failed"
9697
9698         cd $SAVE_PWD
9699         umask $SAVE_UMASK
9700
9701         for num in $(seq $MDSCOUNT); do
9702                 if [ "${identity_old[$num]}" = 1 ]; then
9703                         switch_identity $num false || identity_old[$num]=$?
9704                 fi
9705         done
9706 }
9707 run_test 103a "acl test"
9708
9709 test_103b() {
9710         declare -a pids
9711         local U
9712
9713         for U in {0..511}; do
9714                 {
9715                 local O=$(printf "%04o" $U)
9716
9717                 umask $(printf "%04o" $((511 ^ $O)))
9718                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9719                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9720
9721                 (( $S == ($O & 0666) )) ||
9722                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9723
9724                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9725                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9726                 (( $S == ($O & 0666) )) ||
9727                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9728
9729                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9730                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9731                 (( $S == ($O & 0666) )) ||
9732                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9733                 rm -f $DIR/$tfile.[smp]$0
9734                 } &
9735                 local pid=$!
9736
9737                 # limit the concurrently running threads to 64. LU-11878
9738                 local idx=$((U % 64))
9739                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9740                 pids[idx]=$pid
9741         done
9742         wait
9743 }
9744 run_test 103b "umask lfs setstripe"
9745
9746 test_103c() {
9747         mkdir -p $DIR/$tdir
9748         cp -rp $DIR/$tdir $DIR/$tdir.bak
9749
9750         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9751                 error "$DIR/$tdir shouldn't contain default ACL"
9752         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9753                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9754         true
9755 }
9756 run_test 103c "'cp -rp' won't set empty acl"
9757
9758 test_104a() {
9759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9760
9761         touch $DIR/$tfile
9762         lfs df || error "lfs df failed"
9763         lfs df -ih || error "lfs df -ih failed"
9764         lfs df -h $DIR || error "lfs df -h $DIR failed"
9765         lfs df -i $DIR || error "lfs df -i $DIR failed"
9766         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9767         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9768
9769         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9770         lctl --device %$OSC deactivate
9771         lfs df || error "lfs df with deactivated OSC failed"
9772         lctl --device %$OSC activate
9773         # wait the osc back to normal
9774         wait_osc_import_ready client ost
9775
9776         lfs df || error "lfs df with reactivated OSC failed"
9777         rm -f $DIR/$tfile
9778 }
9779 run_test 104a "lfs df [-ih] [path] test ========================="
9780
9781 test_104b() {
9782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9783         [ $RUNAS_ID -eq $UID ] &&
9784                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9785
9786         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9787                         grep "Permission denied" | wc -l)))
9788         if [ $denied_cnt -ne 0 ]; then
9789                 error "lfs check servers test failed"
9790         fi
9791 }
9792 run_test 104b "$RUNAS lfs check servers test ===================="
9793
9794 test_105a() {
9795         # doesn't work on 2.4 kernels
9796         touch $DIR/$tfile
9797         if $(flock_is_enabled); then
9798                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9799         else
9800                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9801         fi
9802         rm -f $DIR/$tfile
9803 }
9804 run_test 105a "flock when mounted without -o flock test ========"
9805
9806 test_105b() {
9807         touch $DIR/$tfile
9808         if $(flock_is_enabled); then
9809                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9810         else
9811                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9812         fi
9813         rm -f $DIR/$tfile
9814 }
9815 run_test 105b "fcntl when mounted without -o flock test ========"
9816
9817 test_105c() {
9818         touch $DIR/$tfile
9819         if $(flock_is_enabled); then
9820                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9821         else
9822                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9823         fi
9824         rm -f $DIR/$tfile
9825 }
9826 run_test 105c "lockf when mounted without -o flock test"
9827
9828 test_105d() { # bug 15924
9829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9830
9831         test_mkdir $DIR/$tdir
9832         flock_is_enabled || skip_env "mount w/o flock enabled"
9833         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9834         $LCTL set_param fail_loc=0x80000315
9835         flocks_test 2 $DIR/$tdir
9836 }
9837 run_test 105d "flock race (should not freeze) ========"
9838
9839 test_105e() { # bug 22660 && 22040
9840         flock_is_enabled || skip_env "mount w/o flock enabled"
9841
9842         touch $DIR/$tfile
9843         flocks_test 3 $DIR/$tfile
9844 }
9845 run_test 105e "Two conflicting flocks from same process"
9846
9847 test_106() { #bug 10921
9848         test_mkdir $DIR/$tdir
9849         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9850         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9851 }
9852 run_test 106 "attempt exec of dir followed by chown of that dir"
9853
9854 test_107() {
9855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9856
9857         CDIR=`pwd`
9858         local file=core
9859
9860         cd $DIR
9861         rm -f $file
9862
9863         local save_pattern=$(sysctl -n kernel.core_pattern)
9864         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9865         sysctl -w kernel.core_pattern=$file
9866         sysctl -w kernel.core_uses_pid=0
9867
9868         ulimit -c unlimited
9869         sleep 60 &
9870         SLEEPPID=$!
9871
9872         sleep 1
9873
9874         kill -s 11 $SLEEPPID
9875         wait $SLEEPPID
9876         if [ -e $file ]; then
9877                 size=`stat -c%s $file`
9878                 [ $size -eq 0 ] && error "Fail to create core file $file"
9879         else
9880                 error "Fail to create core file $file"
9881         fi
9882         rm -f $file
9883         sysctl -w kernel.core_pattern=$save_pattern
9884         sysctl -w kernel.core_uses_pid=$save_uses_pid
9885         cd $CDIR
9886 }
9887 run_test 107 "Coredump on SIG"
9888
9889 test_110() {
9890         test_mkdir $DIR/$tdir
9891         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9892         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9893                 error "mkdir with 256 char should fail, but did not"
9894         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9895                 error "create with 255 char failed"
9896         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9897                 error "create with 256 char should fail, but did not"
9898
9899         ls -l $DIR/$tdir
9900         rm -rf $DIR/$tdir
9901 }
9902 run_test 110 "filename length checking"
9903
9904 #
9905 # Purpose: To verify dynamic thread (OSS) creation.
9906 #
9907 test_115() {
9908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9909         remote_ost_nodsh && skip "remote OST with nodsh"
9910
9911         # Lustre does not stop service threads once they are started.
9912         # Reset number of running threads to default.
9913         stopall
9914         setupall
9915
9916         local OSTIO_pre
9917         local save_params="$TMP/sanity-$TESTNAME.parameters"
9918
9919         # Get ll_ost_io count before I/O
9920         OSTIO_pre=$(do_facet ost1 \
9921                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9922         # Exit if lustre is not running (ll_ost_io not running).
9923         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9924
9925         echo "Starting with $OSTIO_pre threads"
9926         local thread_max=$((OSTIO_pre * 2))
9927         local rpc_in_flight=$((thread_max * 2))
9928         # Number of I/O Process proposed to be started.
9929         local nfiles
9930         local facets=$(get_facets OST)
9931
9932         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9933         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9934
9935         # Set in_flight to $rpc_in_flight
9936         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9937                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9938         nfiles=${rpc_in_flight}
9939         # Set ost thread_max to $thread_max
9940         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9941
9942         # 5 Minutes should be sufficient for max number of OSS
9943         # threads(thread_max) to be created.
9944         local timeout=300
9945
9946         # Start I/O.
9947         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9948         test_mkdir $DIR/$tdir
9949         for i in $(seq $nfiles); do
9950                 local file=$DIR/$tdir/${tfile}-$i
9951                 $LFS setstripe -c -1 -i 0 $file
9952                 ($WTL $file $timeout)&
9953         done
9954
9955         # I/O Started - Wait for thread_started to reach thread_max or report
9956         # error if thread_started is more than thread_max.
9957         echo "Waiting for thread_started to reach thread_max"
9958         local thread_started=0
9959         local end_time=$((SECONDS + timeout))
9960
9961         while [ $SECONDS -le $end_time ] ; do
9962                 echo -n "."
9963                 # Get ost i/o thread_started count.
9964                 thread_started=$(do_facet ost1 \
9965                         "$LCTL get_param \
9966                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9967                 # Break out if thread_started is equal/greater than thread_max
9968                 if [[ $thread_started -ge $thread_max ]]; then
9969                         echo ll_ost_io thread_started $thread_started, \
9970                                 equal/greater than thread_max $thread_max
9971                         break
9972                 fi
9973                 sleep 1
9974         done
9975
9976         # Cleanup - We have the numbers, Kill i/o jobs if running.
9977         jobcount=($(jobs -p))
9978         for i in $(seq 0 $((${#jobcount[@]}-1)))
9979         do
9980                 kill -9 ${jobcount[$i]}
9981                 if [ $? -ne 0 ] ; then
9982                         echo Warning: \
9983                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9984                 fi
9985         done
9986
9987         # Cleanup files left by WTL binary.
9988         for i in $(seq $nfiles); do
9989                 local file=$DIR/$tdir/${tfile}-$i
9990                 rm -rf $file
9991                 if [ $? -ne 0 ] ; then
9992                         echo "Warning: Failed to delete file $file"
9993                 fi
9994         done
9995
9996         restore_lustre_params <$save_params
9997         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9998
9999         # Error out if no new thread has started or Thread started is greater
10000         # than thread max.
10001         if [[ $thread_started -le $OSTIO_pre ||
10002                         $thread_started -gt $thread_max ]]; then
10003                 error "ll_ost_io: thread_started $thread_started" \
10004                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10005                       "No new thread started or thread started greater " \
10006                       "than thread_max."
10007         fi
10008 }
10009 run_test 115 "verify dynamic thread creation===================="
10010
10011 free_min_max () {
10012         wait_delete_completed
10013         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10014         echo "OST kbytes available: ${AVAIL[@]}"
10015         MAXV=${AVAIL[0]}
10016         MAXI=0
10017         MINV=${AVAIL[0]}
10018         MINI=0
10019         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10020                 #echo OST $i: ${AVAIL[i]}kb
10021                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10022                         MAXV=${AVAIL[i]}
10023                         MAXI=$i
10024                 fi
10025                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10026                         MINV=${AVAIL[i]}
10027                         MINI=$i
10028                 fi
10029         done
10030         echo "Min free space: OST $MINI: $MINV"
10031         echo "Max free space: OST $MAXI: $MAXV"
10032 }
10033
10034 test_116a() { # was previously test_116()
10035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10036         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10037         remote_mds_nodsh && skip "remote MDS with nodsh"
10038
10039         echo -n "Free space priority "
10040         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10041                 head -n1
10042         declare -a AVAIL
10043         free_min_max
10044
10045         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10046         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10047         trap simple_cleanup_common EXIT
10048
10049         # Check if we need to generate uneven OSTs
10050         test_mkdir -p $DIR/$tdir/OST${MINI}
10051         local FILL=$((MINV / 4))
10052         local DIFF=$((MAXV - MINV))
10053         local DIFF2=$((DIFF * 100 / MINV))
10054
10055         local threshold=$(do_facet $SINGLEMDS \
10056                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10057         threshold=${threshold%%%}
10058         echo -n "Check for uneven OSTs: "
10059         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10060
10061         if [[ $DIFF2 -gt $threshold ]]; then
10062                 echo "ok"
10063                 echo "Don't need to fill OST$MINI"
10064         else
10065                 # generate uneven OSTs. Write 2% over the QOS threshold value
10066                 echo "no"
10067                 DIFF=$((threshold - DIFF2 + 2))
10068                 DIFF2=$((MINV * DIFF / 100))
10069                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10070                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10071                         error "setstripe failed"
10072                 DIFF=$((DIFF2 / 2048))
10073                 i=0
10074                 while [ $i -lt $DIFF ]; do
10075                         i=$((i + 1))
10076                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10077                                 bs=2M count=1 2>/dev/null
10078                         echo -n .
10079                 done
10080                 echo .
10081                 sync
10082                 sleep_maxage
10083                 free_min_max
10084         fi
10085
10086         DIFF=$((MAXV - MINV))
10087         DIFF2=$((DIFF * 100 / MINV))
10088         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10089         if [ $DIFF2 -gt $threshold ]; then
10090                 echo "ok"
10091         else
10092                 echo "failed - QOS mode won't be used"
10093                 simple_cleanup_common
10094                 skip "QOS imbalance criteria not met"
10095         fi
10096
10097         MINI1=$MINI
10098         MINV1=$MINV
10099         MAXI1=$MAXI
10100         MAXV1=$MAXV
10101
10102         # now fill using QOS
10103         $LFS setstripe -c 1 $DIR/$tdir
10104         FILL=$((FILL / 200))
10105         if [ $FILL -gt 600 ]; then
10106                 FILL=600
10107         fi
10108         echo "writing $FILL files to QOS-assigned OSTs"
10109         i=0
10110         while [ $i -lt $FILL ]; do
10111                 i=$((i + 1))
10112                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10113                         count=1 2>/dev/null
10114                 echo -n .
10115         done
10116         echo "wrote $i 200k files"
10117         sync
10118         sleep_maxage
10119
10120         echo "Note: free space may not be updated, so measurements might be off"
10121         free_min_max
10122         DIFF2=$((MAXV - MINV))
10123         echo "free space delta: orig $DIFF final $DIFF2"
10124         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10125         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10126         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10127         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10128         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10129         if [[ $DIFF -gt 0 ]]; then
10130                 FILL=$((DIFF2 * 100 / DIFF - 100))
10131                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10132         fi
10133
10134         # Figure out which files were written where
10135         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10136                awk '/'$MINI1': / {print $2; exit}')
10137         echo $UUID
10138         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10139         echo "$MINC files created on smaller OST $MINI1"
10140         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10141                awk '/'$MAXI1': / {print $2; exit}')
10142         echo $UUID
10143         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10144         echo "$MAXC files created on larger OST $MAXI1"
10145         if [[ $MINC -gt 0 ]]; then
10146                 FILL=$((MAXC * 100 / MINC - 100))
10147                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10148         fi
10149         [[ $MAXC -gt $MINC ]] ||
10150                 error_ignore LU-9 "stripe QOS didn't balance free space"
10151         simple_cleanup_common
10152 }
10153 run_test 116a "stripe QOS: free space balance ==================="
10154
10155 test_116b() { # LU-2093
10156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10157         remote_mds_nodsh && skip "remote MDS with nodsh"
10158
10159 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10160         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10161                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10162         [ -z "$old_rr" ] && skip "no QOS"
10163         do_facet $SINGLEMDS lctl set_param \
10164                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10165         mkdir -p $DIR/$tdir
10166         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10167         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10168         do_facet $SINGLEMDS lctl set_param fail_loc=0
10169         rm -rf $DIR/$tdir
10170         do_facet $SINGLEMDS lctl set_param \
10171                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10172 }
10173 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10174
10175 test_117() # bug 10891
10176 {
10177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10178
10179         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10180         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10181         lctl set_param fail_loc=0x21e
10182         > $DIR/$tfile || error "truncate failed"
10183         lctl set_param fail_loc=0
10184         echo "Truncate succeeded."
10185         rm -f $DIR/$tfile
10186 }
10187 run_test 117 "verify osd extend =========="
10188
10189 NO_SLOW_RESENDCOUNT=4
10190 export OLD_RESENDCOUNT=""
10191 set_resend_count () {
10192         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10193         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10194         lctl set_param -n $PROC_RESENDCOUNT $1
10195         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10196 }
10197
10198 # for reduce test_118* time (b=14842)
10199 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10200
10201 # Reset async IO behavior after error case
10202 reset_async() {
10203         FILE=$DIR/reset_async
10204
10205         # Ensure all OSCs are cleared
10206         $LFS setstripe -c -1 $FILE
10207         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10208         sync
10209         rm $FILE
10210 }
10211
10212 test_118a() #bug 11710
10213 {
10214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10215
10216         reset_async
10217
10218         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10219         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10220         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10221
10222         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10223                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10224                 return 1;
10225         fi
10226         rm -f $DIR/$tfile
10227 }
10228 run_test 118a "verify O_SYNC works =========="
10229
10230 test_118b()
10231 {
10232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10233         remote_ost_nodsh && skip "remote OST with nodsh"
10234
10235         reset_async
10236
10237         #define OBD_FAIL_SRV_ENOENT 0x217
10238         set_nodes_failloc "$(osts_nodes)" 0x217
10239         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10240         RC=$?
10241         set_nodes_failloc "$(osts_nodes)" 0
10242         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10243         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10244                     grep -c writeback)
10245
10246         if [[ $RC -eq 0 ]]; then
10247                 error "Must return error due to dropped pages, rc=$RC"
10248                 return 1;
10249         fi
10250
10251         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10252                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10253                 return 1;
10254         fi
10255
10256         echo "Dirty pages not leaked on ENOENT"
10257
10258         # Due to the above error the OSC will issue all RPCs syncronously
10259         # until a subsequent RPC completes successfully without error.
10260         $MULTIOP $DIR/$tfile Ow4096yc
10261         rm -f $DIR/$tfile
10262
10263         return 0
10264 }
10265 run_test 118b "Reclaim dirty pages on fatal error =========="
10266
10267 test_118c()
10268 {
10269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10270
10271         # for 118c, restore the original resend count, LU-1940
10272         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10273                                 set_resend_count $OLD_RESENDCOUNT
10274         remote_ost_nodsh && skip "remote OST with nodsh"
10275
10276         reset_async
10277
10278         #define OBD_FAIL_OST_EROFS               0x216
10279         set_nodes_failloc "$(osts_nodes)" 0x216
10280
10281         # multiop should block due to fsync until pages are written
10282         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10283         MULTIPID=$!
10284         sleep 1
10285
10286         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10287                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10288         fi
10289
10290         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10291                     grep -c writeback)
10292         if [[ $WRITEBACK -eq 0 ]]; then
10293                 error "No page in writeback, writeback=$WRITEBACK"
10294         fi
10295
10296         set_nodes_failloc "$(osts_nodes)" 0
10297         wait $MULTIPID
10298         RC=$?
10299         if [[ $RC -ne 0 ]]; then
10300                 error "Multiop fsync failed, rc=$RC"
10301         fi
10302
10303         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10304         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10305                     grep -c writeback)
10306         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10307                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10308         fi
10309
10310         rm -f $DIR/$tfile
10311         echo "Dirty pages flushed via fsync on EROFS"
10312         return 0
10313 }
10314 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10315
10316 # continue to use small resend count to reduce test_118* time (b=14842)
10317 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10318
10319 test_118d()
10320 {
10321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10322         remote_ost_nodsh && skip "remote OST with nodsh"
10323
10324         reset_async
10325
10326         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10327         set_nodes_failloc "$(osts_nodes)" 0x214
10328         # multiop should block due to fsync until pages are written
10329         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10330         MULTIPID=$!
10331         sleep 1
10332
10333         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10334                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10335         fi
10336
10337         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10338                     grep -c writeback)
10339         if [[ $WRITEBACK -eq 0 ]]; then
10340                 error "No page in writeback, writeback=$WRITEBACK"
10341         fi
10342
10343         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10344         set_nodes_failloc "$(osts_nodes)" 0
10345
10346         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10347         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10348                     grep -c writeback)
10349         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10350                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10351         fi
10352
10353         rm -f $DIR/$tfile
10354         echo "Dirty pages gaurenteed flushed via fsync"
10355         return 0
10356 }
10357 run_test 118d "Fsync validation inject a delay of the bulk =========="
10358
10359 test_118f() {
10360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10361
10362         reset_async
10363
10364         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10365         lctl set_param fail_loc=0x8000040a
10366
10367         # Should simulate EINVAL error which is fatal
10368         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10369         RC=$?
10370         if [[ $RC -eq 0 ]]; then
10371                 error "Must return error due to dropped pages, rc=$RC"
10372         fi
10373
10374         lctl set_param fail_loc=0x0
10375
10376         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10377         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10378         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10379                     grep -c writeback)
10380         if [[ $LOCKED -ne 0 ]]; then
10381                 error "Locked pages remain in cache, locked=$LOCKED"
10382         fi
10383
10384         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10385                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10386         fi
10387
10388         rm -f $DIR/$tfile
10389         echo "No pages locked after fsync"
10390
10391         reset_async
10392         return 0
10393 }
10394 run_test 118f "Simulate unrecoverable OSC side error =========="
10395
10396 test_118g() {
10397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10398
10399         reset_async
10400
10401         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
10402         lctl set_param fail_loc=0x406
10403
10404         # simulate local -ENOMEM
10405         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10406         RC=$?
10407
10408         lctl set_param fail_loc=0
10409         if [[ $RC -eq 0 ]]; then
10410                 error "Must return error due to dropped pages, rc=$RC"
10411         fi
10412
10413         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10414         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10415         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10416                         grep -c writeback)
10417         if [[ $LOCKED -ne 0 ]]; then
10418                 error "Locked pages remain in cache, locked=$LOCKED"
10419         fi
10420
10421         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10422                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10423         fi
10424
10425         rm -f $DIR/$tfile
10426         echo "No pages locked after fsync"
10427
10428         reset_async
10429         return 0
10430 }
10431 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10432
10433 test_118h() {
10434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10435         remote_ost_nodsh && skip "remote OST with nodsh"
10436
10437         reset_async
10438
10439         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10440         set_nodes_failloc "$(osts_nodes)" 0x20e
10441         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10442         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10443         RC=$?
10444
10445         set_nodes_failloc "$(osts_nodes)" 0
10446         if [[ $RC -eq 0 ]]; then
10447                 error "Must return error due to dropped pages, rc=$RC"
10448         fi
10449
10450         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10451         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10452         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10453                     grep -c writeback)
10454         if [[ $LOCKED -ne 0 ]]; then
10455                 error "Locked pages remain in cache, locked=$LOCKED"
10456         fi
10457
10458         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10459                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10460         fi
10461
10462         rm -f $DIR/$tfile
10463         echo "No pages locked after fsync"
10464
10465         return 0
10466 }
10467 run_test 118h "Verify timeout in handling recoverables errors  =========="
10468
10469 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10470
10471 test_118i() {
10472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10473         remote_ost_nodsh && skip "remote OST with nodsh"
10474
10475         reset_async
10476
10477         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10478         set_nodes_failloc "$(osts_nodes)" 0x20e
10479
10480         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10481         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10482         PID=$!
10483         sleep 5
10484         set_nodes_failloc "$(osts_nodes)" 0
10485
10486         wait $PID
10487         RC=$?
10488         if [[ $RC -ne 0 ]]; then
10489                 error "got error, but should be not, rc=$RC"
10490         fi
10491
10492         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10493         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10494         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10495         if [[ $LOCKED -ne 0 ]]; then
10496                 error "Locked pages remain in cache, locked=$LOCKED"
10497         fi
10498
10499         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10500                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10501         fi
10502
10503         rm -f $DIR/$tfile
10504         echo "No pages locked after fsync"
10505
10506         return 0
10507 }
10508 run_test 118i "Fix error before timeout in recoverable error  =========="
10509
10510 [ "$SLOW" = "no" ] && set_resend_count 4
10511
10512 test_118j() {
10513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10514         remote_ost_nodsh && skip "remote OST with nodsh"
10515
10516         reset_async
10517
10518         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10519         set_nodes_failloc "$(osts_nodes)" 0x220
10520
10521         # return -EIO from OST
10522         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10523         RC=$?
10524         set_nodes_failloc "$(osts_nodes)" 0x0
10525         if [[ $RC -eq 0 ]]; then
10526                 error "Must return error due to dropped pages, rc=$RC"
10527         fi
10528
10529         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10530         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10531         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10532         if [[ $LOCKED -ne 0 ]]; then
10533                 error "Locked pages remain in cache, locked=$LOCKED"
10534         fi
10535
10536         # in recoverable error on OST we want resend and stay until it finished
10537         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10538                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10539         fi
10540
10541         rm -f $DIR/$tfile
10542         echo "No pages locked after fsync"
10543
10544         return 0
10545 }
10546 run_test 118j "Simulate unrecoverable OST side error =========="
10547
10548 test_118k()
10549 {
10550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10551         remote_ost_nodsh && skip "remote OSTs with nodsh"
10552
10553         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10554         set_nodes_failloc "$(osts_nodes)" 0x20e
10555         test_mkdir $DIR/$tdir
10556
10557         for ((i=0;i<10;i++)); do
10558                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10559                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10560                 SLEEPPID=$!
10561                 sleep 0.500s
10562                 kill $SLEEPPID
10563                 wait $SLEEPPID
10564         done
10565
10566         set_nodes_failloc "$(osts_nodes)" 0
10567         rm -rf $DIR/$tdir
10568 }
10569 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10570
10571 test_118l() # LU-646
10572 {
10573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10574
10575         test_mkdir $DIR/$tdir
10576         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10577         rm -rf $DIR/$tdir
10578 }
10579 run_test 118l "fsync dir"
10580
10581 test_118m() # LU-3066
10582 {
10583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10584
10585         test_mkdir $DIR/$tdir
10586         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10587         rm -rf $DIR/$tdir
10588 }
10589 run_test 118m "fdatasync dir ========="
10590
10591 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10592
10593 test_118n()
10594 {
10595         local begin
10596         local end
10597
10598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10599         remote_ost_nodsh && skip "remote OSTs with nodsh"
10600
10601         # Sleep to avoid a cached response.
10602         #define OBD_STATFS_CACHE_SECONDS 1
10603         sleep 2
10604
10605         # Inject a 10 second delay in the OST_STATFS handler.
10606         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10607         set_nodes_failloc "$(osts_nodes)" 0x242
10608
10609         begin=$SECONDS
10610         stat --file-system $MOUNT > /dev/null
10611         end=$SECONDS
10612
10613         set_nodes_failloc "$(osts_nodes)" 0
10614
10615         if ((end - begin > 20)); then
10616             error "statfs took $((end - begin)) seconds, expected 10"
10617         fi
10618 }
10619 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10620
10621 test_119a() # bug 11737
10622 {
10623         BSIZE=$((512 * 1024))
10624         directio write $DIR/$tfile 0 1 $BSIZE
10625         # We ask to read two blocks, which is more than a file size.
10626         # directio will indicate an error when requested and actual
10627         # sizes aren't equeal (a normal situation in this case) and
10628         # print actual read amount.
10629         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10630         if [ "$NOB" != "$BSIZE" ]; then
10631                 error "read $NOB bytes instead of $BSIZE"
10632         fi
10633         rm -f $DIR/$tfile
10634 }
10635 run_test 119a "Short directIO read must return actual read amount"
10636
10637 test_119b() # bug 11737
10638 {
10639         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10640
10641         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10642         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10643         sync
10644         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10645                 error "direct read failed"
10646         rm -f $DIR/$tfile
10647 }
10648 run_test 119b "Sparse directIO read must return actual read amount"
10649
10650 test_119c() # bug 13099
10651 {
10652         BSIZE=1048576
10653         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10654         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10655         rm -f $DIR/$tfile
10656 }
10657 run_test 119c "Testing for direct read hitting hole"
10658
10659 test_119d() # bug 15950
10660 {
10661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10662
10663         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10664         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10665         BSIZE=1048576
10666         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10667         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10668         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10669         lctl set_param fail_loc=0x40d
10670         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10671         pid_dio=$!
10672         sleep 1
10673         cat $DIR/$tfile > /dev/null &
10674         lctl set_param fail_loc=0
10675         pid_reads=$!
10676         wait $pid_dio
10677         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10678         sleep 2
10679         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10680         error "the read rpcs have not completed in 2s"
10681         rm -f $DIR/$tfile
10682         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10683 }
10684 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10685
10686 test_120a() {
10687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10688         remote_mds_nodsh && skip "remote MDS with nodsh"
10689         test_mkdir -i0 -c1 $DIR/$tdir
10690         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10691                 skip_env "no early lock cancel on server"
10692
10693         lru_resize_disable mdc
10694         lru_resize_disable osc
10695         cancel_lru_locks mdc
10696         # asynchronous object destroy at MDT could cause bl ast to client
10697         cancel_lru_locks osc
10698
10699         stat $DIR/$tdir > /dev/null
10700         can1=$(do_facet mds1 \
10701                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10702                awk '/ldlm_cancel/ {print $2}')
10703         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10704                awk '/ldlm_bl_callback/ {print $2}')
10705         test_mkdir -i0 -c1 $DIR/$tdir/d1
10706         can2=$(do_facet mds1 \
10707                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10708                awk '/ldlm_cancel/ {print $2}')
10709         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10710                awk '/ldlm_bl_callback/ {print $2}')
10711         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10712         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10713         lru_resize_enable mdc
10714         lru_resize_enable osc
10715 }
10716 run_test 120a "Early Lock Cancel: mkdir test"
10717
10718 test_120b() {
10719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10720         remote_mds_nodsh && skip "remote MDS with nodsh"
10721         test_mkdir $DIR/$tdir
10722         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10723                 skip_env "no early lock cancel on server"
10724
10725         lru_resize_disable mdc
10726         lru_resize_disable osc
10727         cancel_lru_locks mdc
10728         stat $DIR/$tdir > /dev/null
10729         can1=$(do_facet $SINGLEMDS \
10730                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10731                awk '/ldlm_cancel/ {print $2}')
10732         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10733                awk '/ldlm_bl_callback/ {print $2}')
10734         touch $DIR/$tdir/f1
10735         can2=$(do_facet $SINGLEMDS \
10736                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10737                awk '/ldlm_cancel/ {print $2}')
10738         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10739                awk '/ldlm_bl_callback/ {print $2}')
10740         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10741         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10742         lru_resize_enable mdc
10743         lru_resize_enable osc
10744 }
10745 run_test 120b "Early Lock Cancel: create test"
10746
10747 test_120c() {
10748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10749         remote_mds_nodsh && skip "remote MDS with nodsh"
10750         test_mkdir -i0 -c1 $DIR/$tdir
10751         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10752                 skip "no early lock cancel on server"
10753
10754         lru_resize_disable mdc
10755         lru_resize_disable osc
10756         test_mkdir -i0 -c1 $DIR/$tdir/d1
10757         test_mkdir -i0 -c1 $DIR/$tdir/d2
10758         touch $DIR/$tdir/d1/f1
10759         cancel_lru_locks mdc
10760         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10761         can1=$(do_facet mds1 \
10762                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10763                awk '/ldlm_cancel/ {print $2}')
10764         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10765                awk '/ldlm_bl_callback/ {print $2}')
10766         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10767         can2=$(do_facet mds1 \
10768                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10769                awk '/ldlm_cancel/ {print $2}')
10770         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10771                awk '/ldlm_bl_callback/ {print $2}')
10772         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10773         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10774         lru_resize_enable mdc
10775         lru_resize_enable osc
10776 }
10777 run_test 120c "Early Lock Cancel: link test"
10778
10779 test_120d() {
10780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10781         remote_mds_nodsh && skip "remote MDS with nodsh"
10782         test_mkdir -i0 -c1 $DIR/$tdir
10783         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10784                 skip_env "no early lock cancel on server"
10785
10786         lru_resize_disable mdc
10787         lru_resize_disable osc
10788         touch $DIR/$tdir
10789         cancel_lru_locks mdc
10790         stat $DIR/$tdir > /dev/null
10791         can1=$(do_facet mds1 \
10792                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10793                awk '/ldlm_cancel/ {print $2}')
10794         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10795                awk '/ldlm_bl_callback/ {print $2}')
10796         chmod a+x $DIR/$tdir
10797         can2=$(do_facet mds1 \
10798                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10799                awk '/ldlm_cancel/ {print $2}')
10800         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10801                awk '/ldlm_bl_callback/ {print $2}')
10802         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10803         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10804         lru_resize_enable mdc
10805         lru_resize_enable osc
10806 }
10807 run_test 120d "Early Lock Cancel: setattr test"
10808
10809 test_120e() {
10810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10811         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10812                 skip_env "no early lock cancel on server"
10813         remote_mds_nodsh && skip "remote MDS with nodsh"
10814
10815         local dlmtrace_set=false
10816
10817         test_mkdir -i0 -c1 $DIR/$tdir
10818         lru_resize_disable mdc
10819         lru_resize_disable osc
10820         ! $LCTL get_param debug | grep -q dlmtrace &&
10821                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10822         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10823         cancel_lru_locks mdc
10824         cancel_lru_locks osc
10825         dd if=$DIR/$tdir/f1 of=/dev/null
10826         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10827         # XXX client can not do early lock cancel of OST lock
10828         # during unlink (LU-4206), so cancel osc lock now.
10829         sleep 2
10830         cancel_lru_locks osc
10831         can1=$(do_facet mds1 \
10832                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10833                awk '/ldlm_cancel/ {print $2}')
10834         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10835                awk '/ldlm_bl_callback/ {print $2}')
10836         unlink $DIR/$tdir/f1
10837         sleep 5
10838         can2=$(do_facet mds1 \
10839                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10840                awk '/ldlm_cancel/ {print $2}')
10841         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10842                awk '/ldlm_bl_callback/ {print $2}')
10843         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10844                 $LCTL dk $TMP/cancel.debug.txt
10845         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10846                 $LCTL dk $TMP/blocking.debug.txt
10847         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10848         lru_resize_enable mdc
10849         lru_resize_enable osc
10850 }
10851 run_test 120e "Early Lock Cancel: unlink test"
10852
10853 test_120f() {
10854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10855         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10856                 skip_env "no early lock cancel on server"
10857         remote_mds_nodsh && skip "remote MDS with nodsh"
10858
10859         test_mkdir -i0 -c1 $DIR/$tdir
10860         lru_resize_disable mdc
10861         lru_resize_disable osc
10862         test_mkdir -i0 -c1 $DIR/$tdir/d1
10863         test_mkdir -i0 -c1 $DIR/$tdir/d2
10864         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10865         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10866         cancel_lru_locks mdc
10867         cancel_lru_locks osc
10868         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10869         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10870         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10871         # XXX client can not do early lock cancel of OST lock
10872         # during rename (LU-4206), so cancel osc lock now.
10873         sleep 2
10874         cancel_lru_locks osc
10875         can1=$(do_facet mds1 \
10876                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10877                awk '/ldlm_cancel/ {print $2}')
10878         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10879                awk '/ldlm_bl_callback/ {print $2}')
10880         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10881         sleep 5
10882         can2=$(do_facet mds1 \
10883                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10884                awk '/ldlm_cancel/ {print $2}')
10885         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10886                awk '/ldlm_bl_callback/ {print $2}')
10887         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10888         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10889         lru_resize_enable mdc
10890         lru_resize_enable osc
10891 }
10892 run_test 120f "Early Lock Cancel: rename test"
10893
10894 test_120g() {
10895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10896         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10897                 skip_env "no early lock cancel on server"
10898         remote_mds_nodsh && skip "remote MDS with nodsh"
10899
10900         lru_resize_disable mdc
10901         lru_resize_disable osc
10902         count=10000
10903         echo create $count files
10904         test_mkdir $DIR/$tdir
10905         cancel_lru_locks mdc
10906         cancel_lru_locks osc
10907         t0=$(date +%s)
10908
10909         can0=$(do_facet $SINGLEMDS \
10910                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10911                awk '/ldlm_cancel/ {print $2}')
10912         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10913                awk '/ldlm_bl_callback/ {print $2}')
10914         createmany -o $DIR/$tdir/f $count
10915         sync
10916         can1=$(do_facet $SINGLEMDS \
10917                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10918                awk '/ldlm_cancel/ {print $2}')
10919         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10920                awk '/ldlm_bl_callback/ {print $2}')
10921         t1=$(date +%s)
10922         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10923         echo rm $count files
10924         rm -r $DIR/$tdir
10925         sync
10926         can2=$(do_facet $SINGLEMDS \
10927                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10928                awk '/ldlm_cancel/ {print $2}')
10929         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10930                awk '/ldlm_bl_callback/ {print $2}')
10931         t2=$(date +%s)
10932         echo total: $count removes in $((t2-t1))
10933         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10934         sleep 2
10935         # wait for commitment of removal
10936         lru_resize_enable mdc
10937         lru_resize_enable osc
10938 }
10939 run_test 120g "Early Lock Cancel: performance test"
10940
10941 test_121() { #bug #10589
10942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10943
10944         rm -rf $DIR/$tfile
10945         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10946 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10947         lctl set_param fail_loc=0x310
10948         cancel_lru_locks osc > /dev/null
10949         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10950         lctl set_param fail_loc=0
10951         [[ $reads -eq $writes ]] ||
10952                 error "read $reads blocks, must be $writes blocks"
10953 }
10954 run_test 121 "read cancel race ========="
10955
10956 test_123a() { # was test 123, statahead(bug 11401)
10957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10958
10959         SLOWOK=0
10960         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10961                 log "testing UP system. Performance may be lower than expected."
10962                 SLOWOK=1
10963         fi
10964
10965         rm -rf $DIR/$tdir
10966         test_mkdir $DIR/$tdir
10967         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10968         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10969         MULT=10
10970         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10971                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10972
10973                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10974                 lctl set_param -n llite.*.statahead_max 0
10975                 lctl get_param llite.*.statahead_max
10976                 cancel_lru_locks mdc
10977                 cancel_lru_locks osc
10978                 stime=`date +%s`
10979                 time ls -l $DIR/$tdir | wc -l
10980                 etime=`date +%s`
10981                 delta=$((etime - stime))
10982                 log "ls $i files without statahead: $delta sec"
10983                 lctl set_param llite.*.statahead_max=$max
10984
10985                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10986                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10987                 cancel_lru_locks mdc
10988                 cancel_lru_locks osc
10989                 stime=`date +%s`
10990                 time ls -l $DIR/$tdir | wc -l
10991                 etime=`date +%s`
10992                 delta_sa=$((etime - stime))
10993                 log "ls $i files with statahead: $delta_sa sec"
10994                 lctl get_param -n llite.*.statahead_stats
10995                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10996
10997                 [[ $swrong -lt $ewrong ]] &&
10998                         log "statahead was stopped, maybe too many locks held!"
10999                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11000
11001                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11002                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11003                     lctl set_param -n llite.*.statahead_max 0
11004                     lctl get_param llite.*.statahead_max
11005                     cancel_lru_locks mdc
11006                     cancel_lru_locks osc
11007                     stime=`date +%s`
11008                     time ls -l $DIR/$tdir | wc -l
11009                     etime=`date +%s`
11010                     delta=$((etime - stime))
11011                     log "ls $i files again without statahead: $delta sec"
11012                     lctl set_param llite.*.statahead_max=$max
11013                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11014                         if [  $SLOWOK -eq 0 ]; then
11015                                 error "ls $i files is slower with statahead!"
11016                         else
11017                                 log "ls $i files is slower with statahead!"
11018                         fi
11019                         break
11020                     fi
11021                 fi
11022
11023                 [ $delta -gt 20 ] && break
11024                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11025                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11026         done
11027         log "ls done"
11028
11029         stime=`date +%s`
11030         rm -r $DIR/$tdir
11031         sync
11032         etime=`date +%s`
11033         delta=$((etime - stime))
11034         log "rm -r $DIR/$tdir/: $delta seconds"
11035         log "rm done"
11036         lctl get_param -n llite.*.statahead_stats
11037 }
11038 run_test 123a "verify statahead work"
11039
11040 test_123b () { # statahead(bug 15027)
11041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11042
11043         test_mkdir $DIR/$tdir
11044         createmany -o $DIR/$tdir/$tfile-%d 1000
11045
11046         cancel_lru_locks mdc
11047         cancel_lru_locks osc
11048
11049 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11050         lctl set_param fail_loc=0x80000803
11051         ls -lR $DIR/$tdir > /dev/null
11052         log "ls done"
11053         lctl set_param fail_loc=0x0
11054         lctl get_param -n llite.*.statahead_stats
11055         rm -r $DIR/$tdir
11056         sync
11057
11058 }
11059 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11060
11061 test_124a() {
11062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11063         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11064                 skip_env "no lru resize on server"
11065
11066         local NR=2000
11067
11068         test_mkdir $DIR/$tdir
11069
11070         log "create $NR files at $DIR/$tdir"
11071         createmany -o $DIR/$tdir/f $NR ||
11072                 error "failed to create $NR files in $DIR/$tdir"
11073
11074         cancel_lru_locks mdc
11075         ls -l $DIR/$tdir > /dev/null
11076
11077         local NSDIR=""
11078         local LRU_SIZE=0
11079         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11080                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11081                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11082                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11083                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11084                         log "NSDIR=$NSDIR"
11085                         log "NS=$(basename $NSDIR)"
11086                         break
11087                 fi
11088         done
11089
11090         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11091                 skip "Not enough cached locks created!"
11092         fi
11093         log "LRU=$LRU_SIZE"
11094
11095         local SLEEP=30
11096
11097         # We know that lru resize allows one client to hold $LIMIT locks
11098         # for 10h. After that locks begin to be killed by client.
11099         local MAX_HRS=10
11100         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11101         log "LIMIT=$LIMIT"
11102         if [ $LIMIT -lt $LRU_SIZE ]; then
11103                 skip "Limit is too small $LIMIT"
11104         fi
11105
11106         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11107         # killing locks. Some time was spent for creating locks. This means
11108         # that up to the moment of sleep finish we must have killed some of
11109         # them (10-100 locks). This depends on how fast ther were created.
11110         # Many of them were touched in almost the same moment and thus will
11111         # be killed in groups.
11112         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11113
11114         # Use $LRU_SIZE_B here to take into account real number of locks
11115         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11116         local LRU_SIZE_B=$LRU_SIZE
11117         log "LVF=$LVF"
11118         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11119         log "OLD_LVF=$OLD_LVF"
11120         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11121
11122         # Let's make sure that we really have some margin. Client checks
11123         # cached locks every 10 sec.
11124         SLEEP=$((SLEEP+20))
11125         log "Sleep ${SLEEP} sec"
11126         local SEC=0
11127         while ((SEC<$SLEEP)); do
11128                 echo -n "..."
11129                 sleep 5
11130                 SEC=$((SEC+5))
11131                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11132                 echo -n "$LRU_SIZE"
11133         done
11134         echo ""
11135         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11136         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11137
11138         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11139                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11140                 unlinkmany $DIR/$tdir/f $NR
11141                 return
11142         }
11143
11144         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11145         log "unlink $NR files at $DIR/$tdir"
11146         unlinkmany $DIR/$tdir/f $NR
11147 }
11148 run_test 124a "lru resize ======================================="
11149
11150 get_max_pool_limit()
11151 {
11152         local limit=$($LCTL get_param \
11153                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11154         local max=0
11155         for l in $limit; do
11156                 if [[ $l -gt $max ]]; then
11157                         max=$l
11158                 fi
11159         done
11160         echo $max
11161 }
11162
11163 test_124b() {
11164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11165         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11166                 skip_env "no lru resize on server"
11167
11168         LIMIT=$(get_max_pool_limit)
11169
11170         NR=$(($(default_lru_size)*20))
11171         if [[ $NR -gt $LIMIT ]]; then
11172                 log "Limit lock number by $LIMIT locks"
11173                 NR=$LIMIT
11174         fi
11175
11176         IFree=$(mdsrate_inodes_available)
11177         if [ $IFree -lt $NR ]; then
11178                 log "Limit lock number by $IFree inodes"
11179                 NR=$IFree
11180         fi
11181
11182         lru_resize_disable mdc
11183         test_mkdir -p $DIR/$tdir/disable_lru_resize
11184
11185         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11186         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11187         cancel_lru_locks mdc
11188         stime=`date +%s`
11189         PID=""
11190         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11191         PID="$PID $!"
11192         sleep 2
11193         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11194         PID="$PID $!"
11195         sleep 2
11196         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11197         PID="$PID $!"
11198         wait $PID
11199         etime=`date +%s`
11200         nolruresize_delta=$((etime-stime))
11201         log "ls -la time: $nolruresize_delta seconds"
11202         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11203         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11204
11205         lru_resize_enable mdc
11206         test_mkdir -p $DIR/$tdir/enable_lru_resize
11207
11208         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11209         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11210         cancel_lru_locks mdc
11211         stime=`date +%s`
11212         PID=""
11213         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11214         PID="$PID $!"
11215         sleep 2
11216         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11217         PID="$PID $!"
11218         sleep 2
11219         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11220         PID="$PID $!"
11221         wait $PID
11222         etime=`date +%s`
11223         lruresize_delta=$((etime-stime))
11224         log "ls -la time: $lruresize_delta seconds"
11225         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11226
11227         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11228                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11229         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11230                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11231         else
11232                 log "lru resize performs the same with no lru resize"
11233         fi
11234         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11235 }
11236 run_test 124b "lru resize (performance test) ======================="
11237
11238 test_124c() {
11239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11240         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11241                 skip_env "no lru resize on server"
11242
11243         # cache ununsed locks on client
11244         local nr=100
11245         cancel_lru_locks mdc
11246         test_mkdir $DIR/$tdir
11247         createmany -o $DIR/$tdir/f $nr ||
11248                 error "failed to create $nr files in $DIR/$tdir"
11249         ls -l $DIR/$tdir > /dev/null
11250
11251         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11252         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11253         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11254         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11255         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11256
11257         # set lru_max_age to 1 sec
11258         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11259         echo "sleep $((recalc_p * 2)) seconds..."
11260         sleep $((recalc_p * 2))
11261
11262         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11263         # restore lru_max_age
11264         $LCTL set_param -n $nsdir.lru_max_age $max_age
11265         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11266         unlinkmany $DIR/$tdir/f $nr
11267 }
11268 run_test 124c "LRUR cancel very aged locks"
11269
11270 test_124d() {
11271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11272         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11273                 skip_env "no lru resize on server"
11274
11275         # cache ununsed locks on client
11276         local nr=100
11277
11278         lru_resize_disable mdc
11279         stack_trap "lru_resize_enable mdc" EXIT
11280
11281         cancel_lru_locks mdc
11282
11283         # asynchronous object destroy at MDT could cause bl ast to client
11284         test_mkdir $DIR/$tdir
11285         createmany -o $DIR/$tdir/f $nr ||
11286                 error "failed to create $nr files in $DIR/$tdir"
11287         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11288
11289         ls -l $DIR/$tdir > /dev/null
11290
11291         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11292         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11293         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11294         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11295
11296         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11297
11298         # set lru_max_age to 1 sec
11299         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11300         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11301
11302         echo "sleep $((recalc_p * 2)) seconds..."
11303         sleep $((recalc_p * 2))
11304
11305         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11306
11307         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11308 }
11309 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11310
11311 test_125() { # 13358
11312         $LCTL get_param -n llite.*.client_type | grep -q local ||
11313                 skip "must run as local client"
11314         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11315                 skip_env "must have acl enabled"
11316         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11317
11318         test_mkdir $DIR/$tdir
11319         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11320         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
11321         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
11322 }
11323 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
11324
11325 test_126() { # bug 12829/13455
11326         $GSS && skip_env "must run as gss disabled"
11327         $LCTL get_param -n llite.*.client_type | grep -q local ||
11328                 skip "must run as local client"
11329         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
11330
11331         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
11332         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
11333         rm -f $DIR/$tfile
11334         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
11335 }
11336 run_test 126 "check that the fsgid provided by the client is taken into account"
11337
11338 test_127a() { # bug 15521
11339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11340
11341         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
11342         $LCTL set_param osc.*.stats=0
11343         FSIZE=$((2048 * 1024))
11344         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
11345         cancel_lru_locks osc
11346         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
11347
11348         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
11349         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
11350                 echo "got $COUNT $NAME"
11351                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
11352                 eval $NAME=$COUNT || error "Wrong proc format"
11353
11354                 case $NAME in
11355                         read_bytes|write_bytes)
11356                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
11357                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
11358                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
11359                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
11360                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
11361                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
11362                                 error "sumsquare is too small: $SUMSQ"
11363                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
11364                                 error "sumsquare is too big: $SUMSQ"
11365                         ;;
11366                         *) ;;
11367                 esac
11368         done < $DIR/${tfile}.tmp
11369
11370         #check that we actually got some stats
11371         [ "$read_bytes" ] || error "Missing read_bytes stats"
11372         [ "$write_bytes" ] || error "Missing write_bytes stats"
11373         [ "$read_bytes" != 0 ] || error "no read done"
11374         [ "$write_bytes" != 0 ] || error "no write done"
11375 }
11376 run_test 127a "verify the client stats are sane"
11377
11378 test_127b() { # bug LU-333
11379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11380         local name count samp unit min max sum sumsq
11381
11382         $LCTL set_param llite.*.stats=0
11383
11384         # perform 2 reads and writes so MAX is different from SUM.
11385         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11386         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11387         cancel_lru_locks osc
11388         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11389         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11390
11391         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
11392         while read name count samp unit min max sum sumsq; do
11393                 echo "got $count $name"
11394                 eval $name=$count || error "Wrong proc format"
11395
11396                 case $name in
11397                 read_bytes)
11398                         [ $count -ne 2 ] && error "count is not 2: $count"
11399                         [ $min -ne $PAGE_SIZE ] &&
11400                                 error "min is not $PAGE_SIZE: $min"
11401                         [ $max -ne $PAGE_SIZE ] &&
11402                                 error "max is incorrect: $max"
11403                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
11404                                 error "sum is wrong: $sum"
11405                         ;;
11406                 write_bytes)
11407                         [ $count -ne 2 ] && error "count is not 2: $count"
11408                         [ $min -ne $PAGE_SIZE ] &&
11409                                 error "min is not $PAGE_SIZE: $min"
11410                         [ $max -ne $PAGE_SIZE ] &&
11411                                 error "max is incorrect: $max"
11412                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
11413                                 error "sum is wrong: $sum"
11414                         ;;
11415                 *) ;;
11416                 esac
11417         done < $TMP/$tfile.tmp
11418
11419         #check that we actually got some stats
11420         [ "$read_bytes" ] || error "Missing read_bytes stats"
11421         [ "$write_bytes" ] || error "Missing write_bytes stats"
11422         [ "$read_bytes" != 0 ] || error "no read done"
11423         [ "$write_bytes" != 0 ] || error "no write done"
11424
11425         rm -f $TMP/${tfile}.tmp
11426 }
11427 run_test 127b "verify the llite client stats are sane"
11428
11429 test_127c() { # LU-12394
11430         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11431         local size
11432         local bsize
11433         local reads
11434         local writes
11435         local count
11436
11437         $LCTL set_param llite.*.extents_stats=1
11438         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
11439
11440         # Use two stripes so there is enough space in default config
11441         $LFS setstripe -c 2 $DIR/$tfile
11442
11443         # Extent stats start at 0-4K and go in power of two buckets
11444         # LL_HIST_START = 12 --> 2^12 = 4K
11445         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
11446         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
11447         # small configs
11448         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
11449                 do
11450                 # Write and read, 2x each, second time at a non-zero offset
11451                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
11452                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
11453                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
11454                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
11455                 rm -f $DIR/$tfile
11456         done
11457
11458         $LCTL get_param llite.*.extents_stats
11459
11460         count=2
11461         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
11462                 do
11463                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
11464                                 grep -m 1 $bsize)
11465                 reads=$(echo $bucket | awk '{print $5}')
11466                 writes=$(echo $bucket | awk '{print $9}')
11467                 [ "$reads" -eq $count ] ||
11468                         error "$reads reads in < $bsize bucket, expect $count"
11469                 [ "$writes" -eq $count ] ||
11470                         error "$writes writes in < $bsize bucket, expect $count"
11471         done
11472
11473         # Test mmap write and read
11474         $LCTL set_param llite.*.extents_stats=c
11475         size=512
11476         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
11477         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
11478         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
11479
11480         $LCTL get_param llite.*.extents_stats
11481
11482         count=$(((size*1024) / PAGE_SIZE))
11483
11484         bsize=$((2 * PAGE_SIZE / 1024))K
11485
11486         bucket=$($LCTL get_param -n llite.*.extents_stats |
11487                         grep -m 1 $bsize)
11488         reads=$(echo $bucket | awk '{print $5}')
11489         writes=$(echo $bucket | awk '{print $9}')
11490         # mmap writes fault in the page first, creating an additonal read
11491         [ "$reads" -eq $((2 * count)) ] ||
11492                 error "$reads reads in < $bsize bucket, expect $count"
11493         [ "$writes" -eq $count ] ||
11494                 error "$writes writes in < $bsize bucket, expect $count"
11495 }
11496 run_test 127c "test llite extent stats with regular & mmap i/o"
11497
11498 test_128() { # bug 15212
11499         touch $DIR/$tfile
11500         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11501                 find $DIR/$tfile
11502                 find $DIR/$tfile
11503         EOF
11504
11505         result=$(grep error $TMP/$tfile.log)
11506         rm -f $DIR/$tfile $TMP/$tfile.log
11507         [ -z "$result" ] ||
11508                 error "consecutive find's under interactive lfs failed"
11509 }
11510 run_test 128 "interactive lfs for 2 consecutive find's"
11511
11512 set_dir_limits () {
11513         local mntdev
11514         local canondev
11515         local node
11516
11517         local ldproc=/proc/fs/ldiskfs
11518         local facets=$(get_facets MDS)
11519
11520         for facet in ${facets//,/ }; do
11521                 canondev=$(ldiskfs_canon \
11522                            *.$(convert_facet2label $facet).mntdev $facet)
11523                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11524                         ldproc=/sys/fs/ldiskfs
11525                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11526                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11527         done
11528 }
11529
11530 check_mds_dmesg() {
11531         local facets=$(get_facets MDS)
11532         for facet in ${facets//,/ }; do
11533                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11534         done
11535         return 1
11536 }
11537
11538 test_129() {
11539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11540         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11541                 skip "Need MDS version with at least 2.5.56"
11542         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11543                 skip_env "ldiskfs only test"
11544         fi
11545         remote_mds_nodsh && skip "remote MDS with nodsh"
11546
11547         local ENOSPC=28
11548         local EFBIG=27
11549         local has_warning=false
11550
11551         rm -rf $DIR/$tdir
11552         mkdir -p $DIR/$tdir
11553
11554         # block size of mds1
11555         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11556         set_dir_limits $maxsize $maxsize
11557         local dirsize=$(stat -c%s "$DIR/$tdir")
11558         local nfiles=0
11559         while [[ $dirsize -le $maxsize ]]; do
11560                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11561                 rc=$?
11562                 if ! $has_warning; then
11563                         check_mds_dmesg '"is approaching"' && has_warning=true
11564                 fi
11565                 # check two errors:
11566                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11567                 # EFBIG for previous versions included in ldiskfs series
11568                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11569                         set_dir_limits 0 0
11570                         echo "return code $rc received as expected"
11571
11572                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11573                                 error_exit "create failed w/o dir size limit"
11574
11575                         check_mds_dmesg '"has reached"' ||
11576                                 error_exit "reached message should be output"
11577
11578                         [ $has_warning = "false" ] &&
11579                                 error_exit "warning message should be output"
11580
11581                         dirsize=$(stat -c%s "$DIR/$tdir")
11582
11583                         [[ $dirsize -ge $maxsize ]] && return 0
11584                         error_exit "current dir size $dirsize, " \
11585                                    "previous limit $maxsize"
11586                 elif [ $rc -ne 0 ]; then
11587                         set_dir_limits 0 0
11588                         error_exit "return $rc received instead of expected " \
11589                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11590                 fi
11591                 nfiles=$((nfiles + 1))
11592                 dirsize=$(stat -c%s "$DIR/$tdir")
11593         done
11594
11595         set_dir_limits 0 0
11596         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11597 }
11598 run_test 129 "test directory size limit ========================"
11599
11600 OLDIFS="$IFS"
11601 cleanup_130() {
11602         trap 0
11603         IFS="$OLDIFS"
11604 }
11605
11606 test_130a() {
11607         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11608         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11609
11610         trap cleanup_130 EXIT RETURN
11611
11612         local fm_file=$DIR/$tfile
11613         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11614         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11615                 error "dd failed for $fm_file"
11616
11617         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11618         filefrag -ves $fm_file
11619         RC=$?
11620         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11621                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11622         [ $RC != 0 ] && error "filefrag $fm_file failed"
11623
11624         filefrag_op=$(filefrag -ve -k $fm_file |
11625                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11626         lun=$($LFS getstripe -i $fm_file)
11627
11628         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11629         IFS=$'\n'
11630         tot_len=0
11631         for line in $filefrag_op
11632         do
11633                 frag_lun=`echo $line | cut -d: -f5`
11634                 ext_len=`echo $line | cut -d: -f4`
11635                 if (( $frag_lun != $lun )); then
11636                         cleanup_130
11637                         error "FIEMAP on 1-stripe file($fm_file) failed"
11638                         return
11639                 fi
11640                 (( tot_len += ext_len ))
11641         done
11642
11643         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11644                 cleanup_130
11645                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11646                 return
11647         fi
11648
11649         cleanup_130
11650
11651         echo "FIEMAP on single striped file succeeded"
11652 }
11653 run_test 130a "FIEMAP (1-stripe file)"
11654
11655 test_130b() {
11656         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11657
11658         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11659         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11660
11661         trap cleanup_130 EXIT RETURN
11662
11663         local fm_file=$DIR/$tfile
11664         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11665                         error "setstripe on $fm_file"
11666         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11667                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11668
11669         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11670                 error "dd failed on $fm_file"
11671
11672         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11673         filefrag_op=$(filefrag -ve -k $fm_file |
11674                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11675
11676         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11677                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11678
11679         IFS=$'\n'
11680         tot_len=0
11681         num_luns=1
11682         for line in $filefrag_op
11683         do
11684                 frag_lun=$(echo $line | cut -d: -f5 |
11685                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11686                 ext_len=$(echo $line | cut -d: -f4)
11687                 if (( $frag_lun != $last_lun )); then
11688                         if (( tot_len != 1024 )); then
11689                                 cleanup_130
11690                                 error "FIEMAP on $fm_file failed; returned " \
11691                                 "len $tot_len for OST $last_lun instead of 1024"
11692                                 return
11693                         else
11694                                 (( num_luns += 1 ))
11695                                 tot_len=0
11696                         fi
11697                 fi
11698                 (( tot_len += ext_len ))
11699                 last_lun=$frag_lun
11700         done
11701         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11702                 cleanup_130
11703                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11704                         "luns or wrong len for OST $last_lun"
11705                 return
11706         fi
11707
11708         cleanup_130
11709
11710         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11711 }
11712 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11713
11714 test_130c() {
11715         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11716
11717         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11718         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11719
11720         trap cleanup_130 EXIT RETURN
11721
11722         local fm_file=$DIR/$tfile
11723         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11724         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11725                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11726
11727         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11728                         error "dd failed on $fm_file"
11729
11730         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11731         filefrag_op=$(filefrag -ve -k $fm_file |
11732                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11733
11734         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11735                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11736
11737         IFS=$'\n'
11738         tot_len=0
11739         num_luns=1
11740         for line in $filefrag_op
11741         do
11742                 frag_lun=$(echo $line | cut -d: -f5 |
11743                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11744                 ext_len=$(echo $line | cut -d: -f4)
11745                 if (( $frag_lun != $last_lun )); then
11746                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11747                         if (( logical != 512 )); then
11748                                 cleanup_130
11749                                 error "FIEMAP on $fm_file failed; returned " \
11750                                 "logical start for lun $logical instead of 512"
11751                                 return
11752                         fi
11753                         if (( tot_len != 512 )); then
11754                                 cleanup_130
11755                                 error "FIEMAP on $fm_file failed; returned " \
11756                                 "len $tot_len for OST $last_lun instead of 1024"
11757                                 return
11758                         else
11759                                 (( num_luns += 1 ))
11760                                 tot_len=0
11761                         fi
11762                 fi
11763                 (( tot_len += ext_len ))
11764                 last_lun=$frag_lun
11765         done
11766         if (( num_luns != 2 || tot_len != 512 )); then
11767                 cleanup_130
11768                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11769                         "luns or wrong len for OST $last_lun"
11770                 return
11771         fi
11772
11773         cleanup_130
11774
11775         echo "FIEMAP on 2-stripe file with hole succeeded"
11776 }
11777 run_test 130c "FIEMAP (2-stripe file with hole)"
11778
11779 test_130d() {
11780         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11781
11782         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11783         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11784
11785         trap cleanup_130 EXIT RETURN
11786
11787         local fm_file=$DIR/$tfile
11788         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11789                         error "setstripe on $fm_file"
11790         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11791                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11792
11793         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11794         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11795                 error "dd failed on $fm_file"
11796
11797         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11798         filefrag_op=$(filefrag -ve -k $fm_file |
11799                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11800
11801         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11802                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11803
11804         IFS=$'\n'
11805         tot_len=0
11806         num_luns=1
11807         for line in $filefrag_op
11808         do
11809                 frag_lun=$(echo $line | cut -d: -f5 |
11810                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11811                 ext_len=$(echo $line | cut -d: -f4)
11812                 if (( $frag_lun != $last_lun )); then
11813                         if (( tot_len != 1024 )); then
11814                                 cleanup_130
11815                                 error "FIEMAP on $fm_file failed; returned " \
11816                                 "len $tot_len for OST $last_lun instead of 1024"
11817                                 return
11818                         else
11819                                 (( num_luns += 1 ))
11820                                 tot_len=0
11821                         fi
11822                 fi
11823                 (( tot_len += ext_len ))
11824                 last_lun=$frag_lun
11825         done
11826         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11827                 cleanup_130
11828                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11829                         "luns or wrong len for OST $last_lun"
11830                 return
11831         fi
11832
11833         cleanup_130
11834
11835         echo "FIEMAP on N-stripe file succeeded"
11836 }
11837 run_test 130d "FIEMAP (N-stripe file)"
11838
11839 test_130e() {
11840         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11841
11842         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11843         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11844
11845         trap cleanup_130 EXIT RETURN
11846
11847         local fm_file=$DIR/$tfile
11848         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11849         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11850                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11851
11852         NUM_BLKS=512
11853         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11854         for ((i = 0; i < $NUM_BLKS; i++))
11855         do
11856                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11857         done
11858
11859         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11860         filefrag_op=$(filefrag -ve -k $fm_file |
11861                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11862
11863         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11864                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11865
11866         IFS=$'\n'
11867         tot_len=0
11868         num_luns=1
11869         for line in $filefrag_op
11870         do
11871                 frag_lun=$(echo $line | cut -d: -f5 |
11872                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11873                 ext_len=$(echo $line | cut -d: -f4)
11874                 if (( $frag_lun != $last_lun )); then
11875                         if (( tot_len != $EXPECTED_LEN )); then
11876                                 cleanup_130
11877                                 error "FIEMAP on $fm_file failed; returned " \
11878                                 "len $tot_len for OST $last_lun instead " \
11879                                 "of $EXPECTED_LEN"
11880                                 return
11881                         else
11882                                 (( num_luns += 1 ))
11883                                 tot_len=0
11884                         fi
11885                 fi
11886                 (( tot_len += ext_len ))
11887                 last_lun=$frag_lun
11888         done
11889         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11890                 cleanup_130
11891                 error "FIEMAP on $fm_file failed; returned wrong number " \
11892                         "of luns or wrong len for OST $last_lun"
11893                 return
11894         fi
11895
11896         cleanup_130
11897
11898         echo "FIEMAP with continuation calls succeeded"
11899 }
11900 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11901
11902 test_130f() {
11903         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11904         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11905
11906         local fm_file=$DIR/$tfile
11907         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
11908                 error "multiop create with lov_delay_create on $fm_file"
11909
11910         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11911         filefrag_extents=$(filefrag -vek $fm_file |
11912                            awk '/extents? found/ { print $2 }')
11913         if [[ "$filefrag_extents" != "0" ]]; then
11914                 error "FIEMAP on $fm_file failed; " \
11915                       "returned $filefrag_extents expected 0"
11916         fi
11917
11918         rm -f $fm_file
11919 }
11920 run_test 130f "FIEMAP (unstriped file)"
11921
11922 # Test for writev/readv
11923 test_131a() {
11924         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
11925                 error "writev test failed"
11926         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
11927                 error "readv failed"
11928         rm -f $DIR/$tfile
11929 }
11930 run_test 131a "test iov's crossing stripe boundary for writev/readv"
11931
11932 test_131b() {
11933         local fsize=$((524288 + 1048576 + 1572864))
11934         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
11935                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11936                         error "append writev test failed"
11937
11938         ((fsize += 1572864 + 1048576))
11939         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
11940                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11941                         error "append writev test failed"
11942         rm -f $DIR/$tfile
11943 }
11944 run_test 131b "test append writev"
11945
11946 test_131c() {
11947         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
11948         error "NOT PASS"
11949 }
11950 run_test 131c "test read/write on file w/o objects"
11951
11952 test_131d() {
11953         rwv -f $DIR/$tfile -w -n 1 1572864
11954         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
11955         if [ "$NOB" != 1572864 ]; then
11956                 error "Short read filed: read $NOB bytes instead of 1572864"
11957         fi
11958         rm -f $DIR/$tfile
11959 }
11960 run_test 131d "test short read"
11961
11962 test_131e() {
11963         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
11964         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
11965         error "read hitting hole failed"
11966         rm -f $DIR/$tfile
11967 }
11968 run_test 131e "test read hitting hole"
11969
11970 check_stats() {
11971         local facet=$1
11972         local op=$2
11973         local want=${3:-0}
11974         local res
11975
11976         case $facet in
11977         mds*) res=$(do_facet $facet \
11978                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
11979                  ;;
11980         ost*) res=$(do_facet $facet \
11981                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
11982                  ;;
11983         *) error "Wrong facet '$facet'" ;;
11984         esac
11985         [ "$res" ] || error "The counter for $op on $facet was not incremented"
11986         # if the argument $3 is zero, it means any stat increment is ok.
11987         if [[ $want -gt 0 ]]; then
11988                 local count=$(echo $res | awk '{ print $2 }')
11989                 [[ $count -ne $want ]] &&
11990                         error "The $op counter on $facet is $count, not $want"
11991         fi
11992 }
11993
11994 test_133a() {
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 testdir=$DIR/${tdir}/stats_testdir
12002
12003         mkdir -p $DIR/${tdir}
12004
12005         # clear stats.
12006         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12007         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12008
12009         # verify mdt stats first.
12010         mkdir ${testdir} || error "mkdir failed"
12011         check_stats $SINGLEMDS "mkdir" 1
12012         touch ${testdir}/${tfile} || error "touch failed"
12013         check_stats $SINGLEMDS "open" 1
12014         check_stats $SINGLEMDS "close" 1
12015         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12016                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12017                 check_stats $SINGLEMDS "mknod" 2
12018         }
12019         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12020         check_stats $SINGLEMDS "unlink" 1
12021         rm -f ${testdir}/${tfile} || error "file remove failed"
12022         check_stats $SINGLEMDS "unlink" 2
12023
12024         # remove working dir and check mdt stats again.
12025         rmdir ${testdir} || error "rmdir failed"
12026         check_stats $SINGLEMDS "rmdir" 1
12027
12028         local testdir1=$DIR/${tdir}/stats_testdir1
12029         mkdir -p ${testdir}
12030         mkdir -p ${testdir1}
12031         touch ${testdir1}/test1
12032         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12033         check_stats $SINGLEMDS "crossdir_rename" 1
12034
12035         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12036         check_stats $SINGLEMDS "samedir_rename" 1
12037
12038         rm -rf $DIR/${tdir}
12039 }
12040 run_test 133a "Verifying MDT stats ========================================"
12041
12042 test_133b() {
12043         local res
12044
12045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12046         remote_ost_nodsh && skip "remote OST with nodsh"
12047         remote_mds_nodsh && skip "remote MDS with nodsh"
12048
12049         local testdir=$DIR/${tdir}/stats_testdir
12050
12051         mkdir -p ${testdir} || error "mkdir failed"
12052         touch ${testdir}/${tfile} || error "touch failed"
12053         cancel_lru_locks mdc
12054
12055         # clear stats.
12056         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12057         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12058
12059         # extra mdt stats verification.
12060         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12061         check_stats $SINGLEMDS "setattr" 1
12062         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12063         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12064         then            # LU-1740
12065                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12066                 check_stats $SINGLEMDS "getattr" 1
12067         fi
12068         rm -rf $DIR/${tdir}
12069
12070         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12071         # so the check below is not reliable
12072         [ $MDSCOUNT -eq 1 ] || return 0
12073
12074         # Sleep to avoid a cached response.
12075         #define OBD_STATFS_CACHE_SECONDS 1
12076         sleep 2
12077         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12078         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12079         $LFS df || error "lfs failed"
12080         check_stats $SINGLEMDS "statfs" 1
12081
12082         # check aggregated statfs (LU-10018)
12083         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12084                 return 0
12085         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12086                 return 0
12087         sleep 2
12088         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12089         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12090         df $DIR
12091         check_stats $SINGLEMDS "statfs" 1
12092
12093         # We want to check that the client didn't send OST_STATFS to
12094         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12095         # extra care is needed here.
12096         if remote_mds; then
12097                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12098                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12099
12100                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12101                 [ "$res" ] && error "OST got STATFS"
12102         fi
12103
12104         return 0
12105 }
12106 run_test 133b "Verifying extra MDT stats =================================="
12107
12108 test_133c() {
12109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12110         remote_ost_nodsh && skip "remote OST with nodsh"
12111         remote_mds_nodsh && skip "remote MDS with nodsh"
12112
12113         local testdir=$DIR/$tdir/stats_testdir
12114
12115         test_mkdir -p $testdir
12116
12117         # verify obdfilter stats.
12118         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12119         sync
12120         cancel_lru_locks osc
12121         wait_delete_completed
12122
12123         # clear stats.
12124         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12125         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12126
12127         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12128                 error "dd failed"
12129         sync
12130         cancel_lru_locks osc
12131         check_stats ost1 "write" 1
12132
12133         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12134         check_stats ost1 "read" 1
12135
12136         > $testdir/$tfile || error "truncate failed"
12137         check_stats ost1 "punch" 1
12138
12139         rm -f $testdir/$tfile || error "file remove failed"
12140         wait_delete_completed
12141         check_stats ost1 "destroy" 1
12142
12143         rm -rf $DIR/$tdir
12144 }
12145 run_test 133c "Verifying OST stats ========================================"
12146
12147 order_2() {
12148         local value=$1
12149         local orig=$value
12150         local order=1
12151
12152         while [ $value -ge 2 ]; do
12153                 order=$((order*2))
12154                 value=$((value/2))
12155         done
12156
12157         if [ $orig -gt $order ]; then
12158                 order=$((order*2))
12159         fi
12160         echo $order
12161 }
12162
12163 size_in_KMGT() {
12164     local value=$1
12165     local size=('K' 'M' 'G' 'T');
12166     local i=0
12167     local size_string=$value
12168
12169     while [ $value -ge 1024 ]; do
12170         if [ $i -gt 3 ]; then
12171             #T is the biggest unit we get here, if that is bigger,
12172             #just return XXXT
12173             size_string=${value}T
12174             break
12175         fi
12176         value=$((value >> 10))
12177         if [ $value -lt 1024 ]; then
12178             size_string=${value}${size[$i]}
12179             break
12180         fi
12181         i=$((i + 1))
12182     done
12183
12184     echo $size_string
12185 }
12186
12187 get_rename_size() {
12188         local size=$1
12189         local context=${2:-.}
12190         local sample=$(do_facet $SINGLEMDS $LCTL \
12191                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12192                 grep -A1 $context |
12193                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12194         echo $sample
12195 }
12196
12197 test_133d() {
12198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12199         remote_ost_nodsh && skip "remote OST with nodsh"
12200         remote_mds_nodsh && skip "remote MDS with nodsh"
12201         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12202                 skip_env "MDS doesn't support rename stats"
12203
12204         local testdir1=$DIR/${tdir}/stats_testdir1
12205         local testdir2=$DIR/${tdir}/stats_testdir2
12206         mkdir -p $DIR/${tdir}
12207
12208         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12209
12210         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12211         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12212
12213         createmany -o $testdir1/test 512 || error "createmany failed"
12214
12215         # check samedir rename size
12216         mv ${testdir1}/test0 ${testdir1}/test_0
12217
12218         local testdir1_size=$(ls -l $DIR/${tdir} |
12219                 awk '/stats_testdir1/ {print $5}')
12220         local testdir2_size=$(ls -l $DIR/${tdir} |
12221                 awk '/stats_testdir2/ {print $5}')
12222
12223         testdir1_size=$(order_2 $testdir1_size)
12224         testdir2_size=$(order_2 $testdir2_size)
12225
12226         testdir1_size=$(size_in_KMGT $testdir1_size)
12227         testdir2_size=$(size_in_KMGT $testdir2_size)
12228
12229         echo "source rename dir size: ${testdir1_size}"
12230         echo "target rename dir size: ${testdir2_size}"
12231
12232         local cmd="do_facet $SINGLEMDS $LCTL "
12233         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12234
12235         eval $cmd || error "$cmd failed"
12236         local samedir=$($cmd | grep 'same_dir')
12237         local same_sample=$(get_rename_size $testdir1_size)
12238         [ -z "$samedir" ] && error "samedir_rename_size count error"
12239         [[ $same_sample -eq 1 ]] ||
12240                 error "samedir_rename_size error $same_sample"
12241         echo "Check same dir rename stats success"
12242
12243         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12244
12245         # check crossdir rename size
12246         mv ${testdir1}/test_0 ${testdir2}/test_0
12247
12248         testdir1_size=$(ls -l $DIR/${tdir} |
12249                 awk '/stats_testdir1/ {print $5}')
12250         testdir2_size=$(ls -l $DIR/${tdir} |
12251                 awk '/stats_testdir2/ {print $5}')
12252
12253         testdir1_size=$(order_2 $testdir1_size)
12254         testdir2_size=$(order_2 $testdir2_size)
12255
12256         testdir1_size=$(size_in_KMGT $testdir1_size)
12257         testdir2_size=$(size_in_KMGT $testdir2_size)
12258
12259         echo "source rename dir size: ${testdir1_size}"
12260         echo "target rename dir size: ${testdir2_size}"
12261
12262         eval $cmd || error "$cmd failed"
12263         local crossdir=$($cmd | grep 'crossdir')
12264         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12265         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12266         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12267         [[ $src_sample -eq 1 ]] ||
12268                 error "crossdir_rename_size error $src_sample"
12269         [[ $tgt_sample -eq 1 ]] ||
12270                 error "crossdir_rename_size error $tgt_sample"
12271         echo "Check cross dir rename stats success"
12272         rm -rf $DIR/${tdir}
12273 }
12274 run_test 133d "Verifying rename_stats ========================================"
12275
12276 test_133e() {
12277         remote_mds_nodsh && skip "remote MDS with nodsh"
12278         remote_ost_nodsh && skip "remote OST with nodsh"
12279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12280
12281         local testdir=$DIR/${tdir}/stats_testdir
12282         local ctr f0 f1 bs=32768 count=42 sum
12283
12284         mkdir -p ${testdir} || error "mkdir failed"
12285
12286         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12287
12288         for ctr in {write,read}_bytes; do
12289                 sync
12290                 cancel_lru_locks osc
12291
12292                 do_facet ost1 $LCTL set_param -n \
12293                         "obdfilter.*.exports.clear=clear"
12294
12295                 if [ $ctr = write_bytes ]; then
12296                         f0=/dev/zero
12297                         f1=${testdir}/${tfile}
12298                 else
12299                         f0=${testdir}/${tfile}
12300                         f1=/dev/null
12301                 fi
12302
12303                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12304                         error "dd failed"
12305                 sync
12306                 cancel_lru_locks osc
12307
12308                 sum=$(do_facet ost1 $LCTL get_param \
12309                         "obdfilter.*.exports.*.stats" |
12310                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12311                                 $1 == ctr { sum += $7 }
12312                                 END { printf("%0.0f", sum) }')
12313
12314                 if ((sum != bs * count)); then
12315                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12316                 fi
12317         done
12318
12319         rm -rf $DIR/${tdir}
12320 }
12321 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
12322
12323 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
12324
12325 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
12326 # not honor the -ignore_readdir_race option correctly. So we call
12327 # error_ignore() rather than error() in these cases. See LU-11152.
12328 error_133() {
12329         if (find --version; do_facet mds1 find --version) |
12330                 grep -q '\b4\.5\.1[1-4]\b'; then
12331                 error_ignore LU-11152 "$@"
12332         else
12333                 error "$@"
12334         fi
12335 }
12336
12337 test_133f() {
12338         # First without trusting modes.
12339         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
12340         echo "proc_dirs='$proc_dirs'"
12341         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
12342         find $proc_dirs -exec cat '{}' \; &> /dev/null
12343
12344         # Second verifying readability.
12345         $LCTL get_param -R '*' &> /dev/null
12346
12347         # Verifing writability with badarea_io.
12348         find $proc_dirs \
12349                 -ignore_readdir_race \
12350                 -type f \
12351                 -not -name force_lbug \
12352                 -not -name changelog_mask \
12353                 -exec badarea_io '{}' \; ||
12354                         error_133 "find $proc_dirs failed"
12355 }
12356 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
12357
12358 test_133g() {
12359         remote_mds_nodsh && skip "remote MDS with nodsh"
12360         remote_ost_nodsh && skip "remote OST with nodsh"
12361
12362         # eventually, this can also be replaced with "lctl get_param -R",
12363         # but not until that option is always available on the server
12364         local facet
12365         for facet in mds1 ost1; do
12366                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
12367                         skip_noexit "Too old lustre on $facet"
12368                 local facet_proc_dirs=$(do_facet $facet \
12369                                         \\\ls -d $proc_regexp 2>/dev/null)
12370                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12371                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12372                 do_facet $facet find $facet_proc_dirs \
12373                         ! -name req_history \
12374                         -exec cat '{}' \\\; &> /dev/null
12375
12376                 do_facet $facet find $facet_proc_dirs \
12377                         ! -name req_history \
12378                         -type f \
12379                         -exec cat '{}' \\\; &> /dev/null ||
12380                                 error "proc file read failed"
12381
12382                 do_facet $facet find $facet_proc_dirs \
12383                         -ignore_readdir_race \
12384                         -type f \
12385                         -not -name force_lbug \
12386                         -not -name changelog_mask \
12387                         -exec badarea_io '{}' \\\; ||
12388                                 error_133 "$facet find $facet_proc_dirs failed"
12389         done
12390
12391         # remount the FS in case writes/reads /proc break the FS
12392         cleanup || error "failed to unmount"
12393         setup || error "failed to setup"
12394         true
12395 }
12396 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
12397
12398 test_133h() {
12399         remote_mds_nodsh && skip "remote MDS with nodsh"
12400         remote_ost_nodsh && skip "remote OST with nodsh"
12401         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
12402                 skip "Need MDS version at least 2.9.54"
12403
12404         local facet
12405
12406         for facet in client mds1 ost1; do
12407                 local facet_proc_dirs=$(do_facet $facet \
12408                                         \\\ls -d $proc_regexp 2> /dev/null)
12409                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12410                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12411                 # Get the list of files that are missing the terminating newline
12412                 local missing=($(do_facet $facet \
12413                         find ${facet_proc_dirs} -type f \|              \
12414                                 while read F\; do                       \
12415                                         awk -v FS='\v' -v RS='\v\v'     \
12416                                         "'END { if(NR>0 &&              \
12417                                         \\\$NF !~ /.*\\\n\$/)           \
12418                                                 print FILENAME}'"       \
12419                                         '\$F'\;                         \
12420                                 done 2>/dev/null))
12421                 [ ${#missing[*]} -eq 0 ] ||
12422                         error "files do not end with newline: ${missing[*]}"
12423         done
12424 }
12425 run_test 133h "Proc files should end with newlines"
12426
12427 test_134a() {
12428         remote_mds_nodsh && skip "remote MDS with nodsh"
12429         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12430                 skip "Need MDS version at least 2.7.54"
12431
12432         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12433         cancel_lru_locks mdc
12434
12435         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12436         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12437         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12438
12439         local nr=1000
12440         createmany -o $DIR/$tdir/f $nr ||
12441                 error "failed to create $nr files in $DIR/$tdir"
12442         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12443
12444         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12445         do_facet mds1 $LCTL set_param fail_loc=0x327
12446         do_facet mds1 $LCTL set_param fail_val=500
12447         touch $DIR/$tdir/m
12448
12449         echo "sleep 10 seconds ..."
12450         sleep 10
12451         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12452
12453         do_facet mds1 $LCTL set_param fail_loc=0
12454         do_facet mds1 $LCTL set_param fail_val=0
12455         [ $lck_cnt -lt $unused ] ||
12456                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
12457
12458         rm $DIR/$tdir/m
12459         unlinkmany $DIR/$tdir/f $nr
12460 }
12461 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
12462
12463 test_134b() {
12464         remote_mds_nodsh && skip "remote MDS with nodsh"
12465         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12466                 skip "Need MDS version at least 2.7.54"
12467
12468         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12469         cancel_lru_locks mdc
12470
12471         local low_wm=$(do_facet mds1 $LCTL get_param -n \
12472                         ldlm.lock_reclaim_threshold_mb)
12473         # disable reclaim temporarily
12474         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
12475
12476         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12477         do_facet mds1 $LCTL set_param fail_loc=0x328
12478         do_facet mds1 $LCTL set_param fail_val=500
12479
12480         $LCTL set_param debug=+trace
12481
12482         local nr=600
12483         createmany -o $DIR/$tdir/f $nr &
12484         local create_pid=$!
12485
12486         echo "Sleep $TIMEOUT seconds ..."
12487         sleep $TIMEOUT
12488         if ! ps -p $create_pid  > /dev/null 2>&1; then
12489                 do_facet mds1 $LCTL set_param fail_loc=0
12490                 do_facet mds1 $LCTL set_param fail_val=0
12491                 do_facet mds1 $LCTL set_param \
12492                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12493                 error "createmany finished incorrectly!"
12494         fi
12495         do_facet mds1 $LCTL set_param fail_loc=0
12496         do_facet mds1 $LCTL set_param fail_val=0
12497         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12498         wait $create_pid || return 1
12499
12500         unlinkmany $DIR/$tdir/f $nr
12501 }
12502 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12503
12504 test_140() { #bug-17379
12505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12506
12507         test_mkdir $DIR/$tdir
12508         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12509         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12510
12511         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12512         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12513         local i=0
12514         while i=$((i + 1)); do
12515                 test_mkdir $i
12516                 cd $i || error "Changing to $i"
12517                 ln -s ../stat stat || error "Creating stat symlink"
12518                 # Read the symlink until ELOOP present,
12519                 # not LBUGing the system is considered success,
12520                 # we didn't overrun the stack.
12521                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12522                 if [ $ret -ne 0 ]; then
12523                         if [ $ret -eq 40 ]; then
12524                                 break  # -ELOOP
12525                         else
12526                                 error "Open stat symlink"
12527                                         return
12528                         fi
12529                 fi
12530         done
12531         i=$((i - 1))
12532         echo "The symlink depth = $i"
12533         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12534                 error "Invalid symlink depth"
12535
12536         # Test recursive symlink
12537         ln -s symlink_self symlink_self
12538         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12539         echo "open symlink_self returns $ret"
12540         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12541 }
12542 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12543
12544 test_150() {
12545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12546
12547         local TF="$TMP/$tfile"
12548
12549         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12550         cp $TF $DIR/$tfile
12551         cancel_lru_locks $OSC
12552         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12553         remount_client $MOUNT
12554         df -P $MOUNT
12555         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12556
12557         $TRUNCATE $TF 6000
12558         $TRUNCATE $DIR/$tfile 6000
12559         cancel_lru_locks $OSC
12560         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12561
12562         echo "12345" >>$TF
12563         echo "12345" >>$DIR/$tfile
12564         cancel_lru_locks $OSC
12565         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12566
12567         echo "12345" >>$TF
12568         echo "12345" >>$DIR/$tfile
12569         cancel_lru_locks $OSC
12570         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12571
12572         rm -f $TF
12573         true
12574 }
12575 run_test 150 "truncate/append tests"
12576
12577 #LU-2902 roc_hit was not able to read all values from lproc
12578 function roc_hit_init() {
12579         local list=$(comma_list $(osts_nodes))
12580         local dir=$DIR/$tdir-check
12581         local file=$dir/$tfile
12582         local BEFORE
12583         local AFTER
12584         local idx
12585
12586         test_mkdir $dir
12587         #use setstripe to do a write to every ost
12588         for i in $(seq 0 $((OSTCOUNT-1))); do
12589                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12590                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12591                 idx=$(printf %04x $i)
12592                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12593                         awk '$1 == "cache_access" {sum += $7}
12594                                 END { printf("%0.0f", sum) }')
12595
12596                 cancel_lru_locks osc
12597                 cat $file >/dev/null
12598
12599                 AFTER=$(get_osd_param $list *OST*$idx stats |
12600                         awk '$1 == "cache_access" {sum += $7}
12601                                 END { printf("%0.0f", sum) }')
12602
12603                 echo BEFORE:$BEFORE AFTER:$AFTER
12604                 if ! let "AFTER - BEFORE == 4"; then
12605                         rm -rf $dir
12606                         error "roc_hit is not safe to use"
12607                 fi
12608                 rm $file
12609         done
12610
12611         rm -rf $dir
12612 }
12613
12614 function roc_hit() {
12615         local list=$(comma_list $(osts_nodes))
12616         echo $(get_osd_param $list '' stats |
12617                 awk '$1 == "cache_hit" {sum += $7}
12618                         END { printf("%0.0f", sum) }')
12619 }
12620
12621 function set_cache() {
12622         local on=1
12623
12624         if [ "$2" == "off" ]; then
12625                 on=0;
12626         fi
12627         local list=$(comma_list $(osts_nodes))
12628         set_osd_param $list '' $1_cache_enable $on
12629
12630         cancel_lru_locks osc
12631 }
12632
12633 test_151() {
12634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12635         remote_ost_nodsh && skip "remote OST with nodsh"
12636
12637         local CPAGES=3
12638         local list=$(comma_list $(osts_nodes))
12639
12640         # check whether obdfilter is cache capable at all
12641         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12642                 skip "not cache-capable obdfilter"
12643         fi
12644
12645         # check cache is enabled on all obdfilters
12646         if get_osd_param $list '' read_cache_enable | grep 0; then
12647                 skip "oss cache is disabled"
12648         fi
12649
12650         set_osd_param $list '' writethrough_cache_enable 1
12651
12652         # check write cache is enabled on all obdfilters
12653         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12654                 skip "oss write cache is NOT enabled"
12655         fi
12656
12657         roc_hit_init
12658
12659         #define OBD_FAIL_OBD_NO_LRU  0x609
12660         do_nodes $list $LCTL set_param fail_loc=0x609
12661
12662         # pages should be in the case right after write
12663         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12664                 error "dd failed"
12665
12666         local BEFORE=$(roc_hit)
12667         cancel_lru_locks osc
12668         cat $DIR/$tfile >/dev/null
12669         local AFTER=$(roc_hit)
12670
12671         do_nodes $list $LCTL set_param fail_loc=0
12672
12673         if ! let "AFTER - BEFORE == CPAGES"; then
12674                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12675         fi
12676
12677         # the following read invalidates the cache
12678         cancel_lru_locks osc
12679         set_osd_param $list '' read_cache_enable 0
12680         cat $DIR/$tfile >/dev/null
12681
12682         # now data shouldn't be found in the cache
12683         BEFORE=$(roc_hit)
12684         cancel_lru_locks osc
12685         cat $DIR/$tfile >/dev/null
12686         AFTER=$(roc_hit)
12687         if let "AFTER - BEFORE != 0"; then
12688                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12689         fi
12690
12691         set_osd_param $list '' read_cache_enable 1
12692         rm -f $DIR/$tfile
12693 }
12694 run_test 151 "test cache on oss and controls ==============================="
12695
12696 test_152() {
12697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12698
12699         local TF="$TMP/$tfile"
12700
12701         # simulate ENOMEM during write
12702 #define OBD_FAIL_OST_NOMEM      0x226
12703         lctl set_param fail_loc=0x80000226
12704         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12705         cp $TF $DIR/$tfile
12706         sync || error "sync failed"
12707         lctl set_param fail_loc=0
12708
12709         # discard client's cache
12710         cancel_lru_locks osc
12711
12712         # simulate ENOMEM during read
12713         lctl set_param fail_loc=0x80000226
12714         cmp $TF $DIR/$tfile || error "cmp failed"
12715         lctl set_param fail_loc=0
12716
12717         rm -f $TF
12718 }
12719 run_test 152 "test read/write with enomem ============================"
12720
12721 test_153() {
12722         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12723 }
12724 run_test 153 "test if fdatasync does not crash ======================="
12725
12726 dot_lustre_fid_permission_check() {
12727         local fid=$1
12728         local ffid=$MOUNT/.lustre/fid/$fid
12729         local test_dir=$2
12730
12731         echo "stat fid $fid"
12732         stat $ffid > /dev/null || error "stat $ffid failed."
12733         echo "touch fid $fid"
12734         touch $ffid || error "touch $ffid failed."
12735         echo "write to fid $fid"
12736         cat /etc/hosts > $ffid || error "write $ffid failed."
12737         echo "read fid $fid"
12738         diff /etc/hosts $ffid || error "read $ffid failed."
12739         echo "append write to fid $fid"
12740         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12741         echo "rename fid $fid"
12742         mv $ffid $test_dir/$tfile.1 &&
12743                 error "rename $ffid to $tfile.1 should fail."
12744         touch $test_dir/$tfile.1
12745         mv $test_dir/$tfile.1 $ffid &&
12746                 error "rename $tfile.1 to $ffid should fail."
12747         rm -f $test_dir/$tfile.1
12748         echo "truncate fid $fid"
12749         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12750         echo "link fid $fid"
12751         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12752         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12753                 echo "setfacl fid $fid"
12754                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12755                 echo "getfacl fid $fid"
12756                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12757         fi
12758         echo "unlink fid $fid"
12759         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12760         echo "mknod fid $fid"
12761         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12762
12763         fid=[0xf00000400:0x1:0x0]
12764         ffid=$MOUNT/.lustre/fid/$fid
12765
12766         echo "stat non-exist fid $fid"
12767         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12768         echo "write to non-exist fid $fid"
12769         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12770         echo "link new fid $fid"
12771         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12772
12773         mkdir -p $test_dir/$tdir
12774         touch $test_dir/$tdir/$tfile
12775         fid=$($LFS path2fid $test_dir/$tdir)
12776         rc=$?
12777         [ $rc -ne 0 ] &&
12778                 error "error: could not get fid for $test_dir/$dir/$tfile."
12779
12780         ffid=$MOUNT/.lustre/fid/$fid
12781
12782         echo "ls $fid"
12783         ls $ffid > /dev/null || error "ls $ffid failed."
12784         echo "touch $fid/$tfile.1"
12785         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12786
12787         echo "touch $MOUNT/.lustre/fid/$tfile"
12788         touch $MOUNT/.lustre/fid/$tfile && \
12789                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12790
12791         echo "setxattr to $MOUNT/.lustre/fid"
12792         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12793
12794         echo "listxattr for $MOUNT/.lustre/fid"
12795         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12796
12797         echo "delxattr from $MOUNT/.lustre/fid"
12798         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12799
12800         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12801         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12802                 error "touch invalid fid should fail."
12803
12804         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12805         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12806                 error "touch non-normal fid should fail."
12807
12808         echo "rename $tdir to $MOUNT/.lustre/fid"
12809         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12810                 error "rename to $MOUNT/.lustre/fid should fail."
12811
12812         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12813         then            # LU-3547
12814                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12815                 local new_obf_mode=777
12816
12817                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12818                 chmod $new_obf_mode $DIR/.lustre/fid ||
12819                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12820
12821                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12822                 [ $obf_mode -eq $new_obf_mode ] ||
12823                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12824
12825                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12826                 chmod $old_obf_mode $DIR/.lustre/fid ||
12827                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12828         fi
12829
12830         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12831         fid=$($LFS path2fid $test_dir/$tfile-2)
12832
12833         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12834         then # LU-5424
12835                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12836                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12837                         error "create lov data thru .lustre failed"
12838         fi
12839         echo "cp /etc/passwd $test_dir/$tfile-2"
12840         cp /etc/passwd $test_dir/$tfile-2 ||
12841                 error "copy to $test_dir/$tfile-2 failed."
12842         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12843         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12844                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12845
12846         rm -rf $test_dir/tfile.lnk
12847         rm -rf $test_dir/$tfile-2
12848 }
12849
12850 test_154A() {
12851         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12852                 skip "Need MDS version at least 2.4.1"
12853
12854         local tf=$DIR/$tfile
12855         touch $tf
12856
12857         local fid=$($LFS path2fid $tf)
12858         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12859
12860         # check that we get the same pathname back
12861         local found=$($LFS fid2path $MOUNT "$fid")
12862         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12863         [ "$found" == "$tf" ] ||
12864                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12865 }
12866 run_test 154A "lfs path2fid and fid2path basic checks"
12867
12868 test_154B() {
12869         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12870                 skip "Need MDS version at least 2.4.1"
12871
12872         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12873         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12874         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12875         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12876
12877         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12878         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12879
12880         # check that we get the same pathname
12881         echo "PFID: $PFID, name: $name"
12882         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12883         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12884         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12885                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12886
12887         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12888 }
12889 run_test 154B "verify the ll_decode_linkea tool"
12890
12891 test_154a() {
12892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12893         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12894         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12895                 skip "Need MDS version at least 2.2.51"
12896         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12897
12898         cp /etc/hosts $DIR/$tfile
12899
12900         fid=$($LFS path2fid $DIR/$tfile)
12901         rc=$?
12902         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
12903
12904         dot_lustre_fid_permission_check "$fid" $DIR ||
12905                 error "dot lustre permission check $fid failed"
12906
12907         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
12908
12909         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
12910
12911         touch $MOUNT/.lustre/file &&
12912                 error "creation is not allowed under .lustre"
12913
12914         mkdir $MOUNT/.lustre/dir &&
12915                 error "mkdir is not allowed under .lustre"
12916
12917         rm -rf $DIR/$tfile
12918 }
12919 run_test 154a "Open-by-FID"
12920
12921 test_154b() {
12922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12923         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12924         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12925         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12926                 skip "Need MDS version at least 2.2.51"
12927
12928         local remote_dir=$DIR/$tdir/remote_dir
12929         local MDTIDX=1
12930         local rc=0
12931
12932         mkdir -p $DIR/$tdir
12933         $LFS mkdir -i $MDTIDX $remote_dir ||
12934                 error "create remote directory failed"
12935
12936         cp /etc/hosts $remote_dir/$tfile
12937
12938         fid=$($LFS path2fid $remote_dir/$tfile)
12939         rc=$?
12940         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
12941
12942         dot_lustre_fid_permission_check "$fid" $remote_dir ||
12943                 error "dot lustre permission check $fid failed"
12944         rm -rf $DIR/$tdir
12945 }
12946 run_test 154b "Open-by-FID for remote directory"
12947
12948 test_154c() {
12949         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12950                 skip "Need MDS version at least 2.4.1"
12951
12952         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
12953         local FID1=$($LFS path2fid $DIR/$tfile.1)
12954         local FID2=$($LFS path2fid $DIR/$tfile.2)
12955         local FID3=$($LFS path2fid $DIR/$tfile.3)
12956
12957         local N=1
12958         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
12959                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
12960                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
12961                 local want=FID$N
12962                 [ "$FID" = "${!want}" ] ||
12963                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
12964                 N=$((N + 1))
12965         done
12966
12967         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
12968         do
12969                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
12970                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
12971                 N=$((N + 1))
12972         done
12973 }
12974 run_test 154c "lfs path2fid and fid2path multiple arguments"
12975
12976 test_154d() {
12977         remote_mds_nodsh && skip "remote MDS with nodsh"
12978         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
12979                 skip "Need MDS version at least 2.5.53"
12980
12981         if remote_mds; then
12982                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
12983         else
12984                 nid="0@lo"
12985         fi
12986         local proc_ofile="mdt.*.exports.'$nid'.open_files"
12987         local fd
12988         local cmd
12989
12990         rm -f $DIR/$tfile
12991         touch $DIR/$tfile
12992
12993         local fid=$($LFS path2fid $DIR/$tfile)
12994         # Open the file
12995         fd=$(free_fd)
12996         cmd="exec $fd<$DIR/$tfile"
12997         eval $cmd
12998         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
12999         echo "$fid_list" | grep "$fid"
13000         rc=$?
13001
13002         cmd="exec $fd>/dev/null"
13003         eval $cmd
13004         if [ $rc -ne 0 ]; then
13005                 error "FID $fid not found in open files list $fid_list"
13006         fi
13007 }
13008 run_test 154d "Verify open file fid"
13009
13010 test_154e()
13011 {
13012         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13013                 skip "Need MDS version at least 2.6.50"
13014
13015         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13016                 error ".lustre returned by readdir"
13017         fi
13018 }
13019 run_test 154e ".lustre is not returned by readdir"
13020
13021 test_154f() {
13022         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13023
13024         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13025         test_mkdir -p -c1 $DIR/$tdir/d
13026         # test dirs inherit from its stripe
13027         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13028         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13029         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13030         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13031         touch $DIR/f
13032
13033         # get fid of parents
13034         local FID0=$($LFS path2fid $DIR/$tdir/d)
13035         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13036         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13037         local FID3=$($LFS path2fid $DIR)
13038
13039         # check that path2fid --parents returns expected <parent_fid>/name
13040         # 1) test for a directory (single parent)
13041         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13042         [ "$parent" == "$FID0/foo1" ] ||
13043                 error "expected parent: $FID0/foo1, got: $parent"
13044
13045         # 2) test for a file with nlink > 1 (multiple parents)
13046         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13047         echo "$parent" | grep -F "$FID1/$tfile" ||
13048                 error "$FID1/$tfile not returned in parent list"
13049         echo "$parent" | grep -F "$FID2/link" ||
13050                 error "$FID2/link not returned in parent list"
13051
13052         # 3) get parent by fid
13053         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13054         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13055         echo "$parent" | grep -F "$FID1/$tfile" ||
13056                 error "$FID1/$tfile not returned in parent list (by fid)"
13057         echo "$parent" | grep -F "$FID2/link" ||
13058                 error "$FID2/link not returned in parent list (by fid)"
13059
13060         # 4) test for entry in root directory
13061         parent=$($LFS path2fid --parents $DIR/f)
13062         echo "$parent" | grep -F "$FID3/f" ||
13063                 error "$FID3/f not returned in parent list"
13064
13065         # 5) test it on root directory
13066         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13067                 error "$MOUNT should not have parents"
13068
13069         # enable xattr caching and check that linkea is correctly updated
13070         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13071         save_lustre_params client "llite.*.xattr_cache" > $save
13072         lctl set_param llite.*.xattr_cache 1
13073
13074         # 6.1) linkea update on rename
13075         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13076
13077         # get parents by fid
13078         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13079         # foo1 should no longer be returned in parent list
13080         echo "$parent" | grep -F "$FID1" &&
13081                 error "$FID1 should no longer be in parent list"
13082         # the new path should appear
13083         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13084                 error "$FID2/$tfile.moved is not in parent list"
13085
13086         # 6.2) linkea update on unlink
13087         rm -f $DIR/$tdir/d/foo2/link
13088         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13089         # foo2/link should no longer be returned in parent list
13090         echo "$parent" | grep -F "$FID2/link" &&
13091                 error "$FID2/link should no longer be in parent list"
13092         true
13093
13094         rm -f $DIR/f
13095         restore_lustre_params < $save
13096         rm -f $save
13097 }
13098 run_test 154f "get parent fids by reading link ea"
13099
13100 test_154g()
13101 {
13102         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13103         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13104            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13105                 skip "Need MDS version at least 2.6.92"
13106
13107         mkdir -p $DIR/$tdir
13108         llapi_fid_test -d $DIR/$tdir
13109 }
13110 run_test 154g "various llapi FID tests"
13111
13112 test_155_small_load() {
13113     local temp=$TMP/$tfile
13114     local file=$DIR/$tfile
13115
13116     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13117         error "dd of=$temp bs=6096 count=1 failed"
13118     cp $temp $file
13119     cancel_lru_locks $OSC
13120     cmp $temp $file || error "$temp $file differ"
13121
13122     $TRUNCATE $temp 6000
13123     $TRUNCATE $file 6000
13124     cmp $temp $file || error "$temp $file differ (truncate1)"
13125
13126     echo "12345" >>$temp
13127     echo "12345" >>$file
13128     cmp $temp $file || error "$temp $file differ (append1)"
13129
13130     echo "12345" >>$temp
13131     echo "12345" >>$file
13132     cmp $temp $file || error "$temp $file differ (append2)"
13133
13134     rm -f $temp $file
13135     true
13136 }
13137
13138 test_155_big_load() {
13139         remote_ost_nodsh && skip "remote OST with nodsh"
13140
13141         local temp=$TMP/$tfile
13142         local file=$DIR/$tfile
13143
13144         free_min_max
13145         local cache_size=$(do_facet ost$((MAXI+1)) \
13146                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13147         local large_file_size=$((cache_size * 2))
13148
13149         echo "OSS cache size: $cache_size KB"
13150         echo "Large file size: $large_file_size KB"
13151
13152         [ $MAXV -le $large_file_size ] &&
13153                 skip_env "max available OST size needs > $large_file_size KB"
13154
13155         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13156
13157         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13158                 error "dd of=$temp bs=$large_file_size count=1k failed"
13159         cp $temp $file
13160         ls -lh $temp $file
13161         cancel_lru_locks osc
13162         cmp $temp $file || error "$temp $file differ"
13163
13164         rm -f $temp $file
13165         true
13166 }
13167
13168 save_writethrough() {
13169         local facets=$(get_facets OST)
13170
13171         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13172 }
13173
13174 test_155a() {
13175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13176
13177         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13178
13179         save_writethrough $p
13180
13181         set_cache read on
13182         set_cache writethrough on
13183         test_155_small_load
13184         restore_lustre_params < $p
13185         rm -f $p
13186 }
13187 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13188
13189 test_155b() {
13190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13191
13192         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13193
13194         save_writethrough $p
13195
13196         set_cache read on
13197         set_cache writethrough off
13198         test_155_small_load
13199         restore_lustre_params < $p
13200         rm -f $p
13201 }
13202 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13203
13204 test_155c() {
13205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13206
13207         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13208
13209         save_writethrough $p
13210
13211         set_cache read off
13212         set_cache writethrough on
13213         test_155_small_load
13214         restore_lustre_params < $p
13215         rm -f $p
13216 }
13217 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13218
13219 test_155d() {
13220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13221
13222         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13223
13224         save_writethrough $p
13225
13226         set_cache read off
13227         set_cache writethrough off
13228         test_155_small_load
13229         restore_lustre_params < $p
13230         rm -f $p
13231 }
13232 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
13233
13234 test_155e() {
13235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13236
13237         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13238
13239         save_writethrough $p
13240
13241         set_cache read on
13242         set_cache writethrough on
13243         test_155_big_load
13244         restore_lustre_params < $p
13245         rm -f $p
13246 }
13247 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
13248
13249 test_155f() {
13250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13251
13252         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13253
13254         save_writethrough $p
13255
13256         set_cache read on
13257         set_cache writethrough off
13258         test_155_big_load
13259         restore_lustre_params < $p
13260         rm -f $p
13261 }
13262 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
13263
13264 test_155g() {
13265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13266
13267         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13268
13269         save_writethrough $p
13270
13271         set_cache read off
13272         set_cache writethrough on
13273         test_155_big_load
13274         restore_lustre_params < $p
13275         rm -f $p
13276 }
13277 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
13278
13279 test_155h() {
13280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13281
13282         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13283
13284         save_writethrough $p
13285
13286         set_cache read off
13287         set_cache writethrough off
13288         test_155_big_load
13289         restore_lustre_params < $p
13290         rm -f $p
13291 }
13292 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
13293
13294 test_156() {
13295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13296         remote_ost_nodsh && skip "remote OST with nodsh"
13297         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
13298                 skip "stats not implemented on old servers"
13299         [ "$ost1_FSTYPE" = "zfs" ] &&
13300                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
13301
13302         local CPAGES=3
13303         local BEFORE
13304         local AFTER
13305         local file="$DIR/$tfile"
13306         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13307
13308         save_writethrough $p
13309         roc_hit_init
13310
13311         log "Turn on read and write cache"
13312         set_cache read on
13313         set_cache writethrough on
13314
13315         log "Write data and read it back."
13316         log "Read should be satisfied from the cache."
13317         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13318         BEFORE=$(roc_hit)
13319         cancel_lru_locks osc
13320         cat $file >/dev/null
13321         AFTER=$(roc_hit)
13322         if ! let "AFTER - BEFORE == CPAGES"; then
13323                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13324         else
13325                 log "cache hits:: before: $BEFORE, after: $AFTER"
13326         fi
13327
13328         log "Read again; it should be satisfied from the cache."
13329         BEFORE=$AFTER
13330         cancel_lru_locks osc
13331         cat $file >/dev/null
13332         AFTER=$(roc_hit)
13333         if ! let "AFTER - BEFORE == CPAGES"; then
13334                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13335         else
13336                 log "cache hits:: before: $BEFORE, after: $AFTER"
13337         fi
13338
13339         log "Turn off the read cache and turn on the write cache"
13340         set_cache read off
13341         set_cache writethrough on
13342
13343         log "Read again; it should be satisfied from the cache."
13344         BEFORE=$(roc_hit)
13345         cancel_lru_locks osc
13346         cat $file >/dev/null
13347         AFTER=$(roc_hit)
13348         if ! let "AFTER - BEFORE == CPAGES"; then
13349                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13350         else
13351                 log "cache hits:: before: $BEFORE, after: $AFTER"
13352         fi
13353
13354         log "Read again; it should not be satisfied from the cache."
13355         BEFORE=$AFTER
13356         cancel_lru_locks osc
13357         cat $file >/dev/null
13358         AFTER=$(roc_hit)
13359         if ! let "AFTER - BEFORE == 0"; then
13360                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13361         else
13362                 log "cache hits:: before: $BEFORE, after: $AFTER"
13363         fi
13364
13365         log "Write data and read it back."
13366         log "Read should be satisfied from the cache."
13367         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13368         BEFORE=$(roc_hit)
13369         cancel_lru_locks osc
13370         cat $file >/dev/null
13371         AFTER=$(roc_hit)
13372         if ! let "AFTER - BEFORE == CPAGES"; then
13373                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13374         else
13375                 log "cache hits:: before: $BEFORE, after: $AFTER"
13376         fi
13377
13378         log "Read again; it should not be satisfied from the cache."
13379         BEFORE=$AFTER
13380         cancel_lru_locks osc
13381         cat $file >/dev/null
13382         AFTER=$(roc_hit)
13383         if ! let "AFTER - BEFORE == 0"; then
13384                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13385         else
13386                 log "cache hits:: before: $BEFORE, after: $AFTER"
13387         fi
13388
13389         log "Turn off read and write cache"
13390         set_cache read off
13391         set_cache writethrough off
13392
13393         log "Write data and read it back"
13394         log "It should not be satisfied from the cache."
13395         rm -f $file
13396         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13397         cancel_lru_locks osc
13398         BEFORE=$(roc_hit)
13399         cat $file >/dev/null
13400         AFTER=$(roc_hit)
13401         if ! let "AFTER - BEFORE == 0"; then
13402                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
13403         else
13404                 log "cache hits:: before: $BEFORE, after: $AFTER"
13405         fi
13406
13407         log "Turn on the read cache and turn off the write cache"
13408         set_cache read on
13409         set_cache writethrough off
13410
13411         log "Write data and read it back"
13412         log "It should not be satisfied from the cache."
13413         rm -f $file
13414         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13415         BEFORE=$(roc_hit)
13416         cancel_lru_locks osc
13417         cat $file >/dev/null
13418         AFTER=$(roc_hit)
13419         if ! let "AFTER - BEFORE == 0"; then
13420                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
13421         else
13422                 log "cache hits:: before: $BEFORE, after: $AFTER"
13423         fi
13424
13425         log "Read again; it should be satisfied from the cache."
13426         BEFORE=$(roc_hit)
13427         cancel_lru_locks osc
13428         cat $file >/dev/null
13429         AFTER=$(roc_hit)
13430         if ! let "AFTER - BEFORE == CPAGES"; then
13431                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13432         else
13433                 log "cache hits:: before: $BEFORE, after: $AFTER"
13434         fi
13435
13436         restore_lustre_params < $p
13437         rm -f $p $file
13438 }
13439 run_test 156 "Verification of tunables"
13440
13441 test_160a() {
13442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13443         remote_mds_nodsh && skip "remote MDS with nodsh"
13444         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13445                 skip "Need MDS version at least 2.2.0"
13446
13447         changelog_register || error "changelog_register failed"
13448         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13449         changelog_users $SINGLEMDS | grep -q $cl_user ||
13450                 error "User $cl_user not found in changelog_users"
13451
13452         # change something
13453         test_mkdir -p $DIR/$tdir/pics/2008/zachy
13454         changelog_clear 0 || error "changelog_clear failed"
13455         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
13456         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
13457         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
13458         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
13459         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
13460         rm $DIR/$tdir/pics/desktop.jpg
13461
13462         changelog_dump | tail -10
13463
13464         echo "verifying changelog mask"
13465         changelog_chmask "-MKDIR"
13466         changelog_chmask "-CLOSE"
13467
13468         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
13469         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
13470
13471         changelog_chmask "+MKDIR"
13472         changelog_chmask "+CLOSE"
13473
13474         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
13475         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13476
13477         changelog_dump | tail -10
13478         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13479         CLOSES=$(changelog_dump | grep -c "CLOSE")
13480         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13481         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13482
13483         # verify contents
13484         echo "verifying target fid"
13485         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13486         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13487         [ "$fidc" == "$fidf" ] ||
13488                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13489         echo "verifying parent fid"
13490         # The FID returned from the Changelog may be the directory shard on
13491         # a different MDT, and not the FID returned by path2fid on the parent.
13492         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13493         # since this is what will matter when recreating this file in the tree.
13494         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13495         local pathp=$($LFS fid2path $MOUNT "$fidp")
13496         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13497                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13498
13499         echo "getting records for $cl_user"
13500         changelog_users $SINGLEMDS
13501         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13502         local nclr=3
13503         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13504                 error "changelog_clear failed"
13505         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13506         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13507         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13508                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13509
13510         local min0_rec=$(changelog_users $SINGLEMDS |
13511                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13512         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13513                           awk '{ print $1; exit; }')
13514
13515         changelog_dump | tail -n 5
13516         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13517         [ $first_rec == $((min0_rec + 1)) ] ||
13518                 error "first index should be $min0_rec + 1 not $first_rec"
13519
13520         # LU-3446 changelog index reset on MDT restart
13521         local cur_rec1=$(changelog_users $SINGLEMDS |
13522                          awk '/^current.index:/ { print $NF }')
13523         changelog_clear 0 ||
13524                 error "clear all changelog records for $cl_user failed"
13525         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13526         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13527                 error "Fail to start $SINGLEMDS"
13528         local cur_rec2=$(changelog_users $SINGLEMDS |
13529                          awk '/^current.index:/ { print $NF }')
13530         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13531         [ $cur_rec1 == $cur_rec2 ] ||
13532                 error "current index should be $cur_rec1 not $cur_rec2"
13533
13534         echo "verifying users from this test are deregistered"
13535         changelog_deregister || error "changelog_deregister failed"
13536         changelog_users $SINGLEMDS | grep -q $cl_user &&
13537                 error "User '$cl_user' still in changelog_users"
13538
13539         # lctl get_param -n mdd.*.changelog_users
13540         # current index: 144
13541         # ID    index (idle seconds)
13542         # cl3   144 (2)
13543         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13544                 # this is the normal case where all users were deregistered
13545                 # make sure no new records are added when no users are present
13546                 local last_rec1=$(changelog_users $SINGLEMDS |
13547                                   awk '/^current.index:/ { print $NF }')
13548                 touch $DIR/$tdir/chloe
13549                 local last_rec2=$(changelog_users $SINGLEMDS |
13550                                   awk '/^current.index:/ { print $NF }')
13551                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13552                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13553         else
13554                 # any changelog users must be leftovers from a previous test
13555                 changelog_users $SINGLEMDS
13556                 echo "other changelog users; can't verify off"
13557         fi
13558 }
13559 run_test 160a "changelog sanity"
13560
13561 test_160b() { # LU-3587
13562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13563         remote_mds_nodsh && skip "remote MDS with nodsh"
13564         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13565                 skip "Need MDS version at least 2.2.0"
13566
13567         changelog_register || error "changelog_register failed"
13568         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13569         changelog_users $SINGLEMDS | grep -q $cl_user ||
13570                 error "User '$cl_user' not found in changelog_users"
13571
13572         local longname1=$(str_repeat a 255)
13573         local longname2=$(str_repeat b 255)
13574
13575         cd $DIR
13576         echo "creating very long named file"
13577         touch $longname1 || error "create of '$longname1' failed"
13578         echo "renaming very long named file"
13579         mv $longname1 $longname2
13580
13581         changelog_dump | grep RENME | tail -n 5
13582         rm -f $longname2
13583 }
13584 run_test 160b "Verify that very long rename doesn't crash in changelog"
13585
13586 test_160c() {
13587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13588         remote_mds_nodsh && skip "remote MDS with nodsh"
13589
13590         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13591                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13592                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13593                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13594
13595         local rc=0
13596
13597         # Registration step
13598         changelog_register || error "changelog_register failed"
13599
13600         rm -rf $DIR/$tdir
13601         mkdir -p $DIR/$tdir
13602         $MCREATE $DIR/$tdir/foo_160c
13603         changelog_chmask "-TRUNC"
13604         $TRUNCATE $DIR/$tdir/foo_160c 200
13605         changelog_chmask "+TRUNC"
13606         $TRUNCATE $DIR/$tdir/foo_160c 199
13607         changelog_dump | tail -n 5
13608         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13609         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13610 }
13611 run_test 160c "verify that changelog log catch the truncate event"
13612
13613 test_160d() {
13614         remote_mds_nodsh && skip "remote MDS with nodsh"
13615         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13617         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13618                 skip "Need MDS version at least 2.7.60"
13619
13620         # Registration step
13621         changelog_register || error "changelog_register failed"
13622
13623         mkdir -p $DIR/$tdir/migrate_dir
13624         changelog_clear 0 || error "changelog_clear failed"
13625
13626         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13627         changelog_dump | tail -n 5
13628         local migrates=$(changelog_dump | grep -c "MIGRT")
13629         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13630 }
13631 run_test 160d "verify that changelog log catch the migrate event"
13632
13633 test_160e() {
13634         remote_mds_nodsh && skip "remote MDS with nodsh"
13635
13636         # Create a user
13637         changelog_register || error "changelog_register failed"
13638
13639         # Delete a future user (expect fail)
13640         local MDT0=$(facet_svc $SINGLEMDS)
13641         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13642         local rc=$?
13643
13644         if [ $rc -eq 0 ]; then
13645                 error "Deleted non-existant user cl77"
13646         elif [ $rc -ne 2 ]; then
13647                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13648         fi
13649
13650         # Clear to a bad index (1 billion should be safe)
13651         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13652         rc=$?
13653
13654         if [ $rc -eq 0 ]; then
13655                 error "Successfully cleared to invalid CL index"
13656         elif [ $rc -ne 22 ]; then
13657                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13658         fi
13659 }
13660 run_test 160e "changelog negative testing (should return errors)"
13661
13662 test_160f() {
13663         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13664         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13665                 skip "Need MDS version at least 2.10.56"
13666
13667         local mdts=$(comma_list $(mdts_nodes))
13668
13669         # Create a user
13670         changelog_register || error "first changelog_register failed"
13671         changelog_register || error "second changelog_register failed"
13672         local cl_users
13673         declare -A cl_user1
13674         declare -A cl_user2
13675         local user_rec1
13676         local user_rec2
13677         local i
13678
13679         # generate some changelog records to accumulate on each MDT
13680         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13681         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13682                 error "create $DIR/$tdir/$tfile failed"
13683
13684         # check changelogs have been generated
13685         local nbcl=$(changelog_dump | wc -l)
13686         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13687
13688         for param in "changelog_max_idle_time=10" \
13689                      "changelog_gc=1" \
13690                      "changelog_min_gc_interval=2" \
13691                      "changelog_min_free_cat_entries=3"; do
13692                 local MDT0=$(facet_svc $SINGLEMDS)
13693                 local var="${param%=*}"
13694                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13695
13696                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13697                 do_nodes $mdts $LCTL set_param mdd.*.$param
13698         done
13699
13700         # force cl_user2 to be idle (1st part)
13701         sleep 9
13702
13703         # simulate changelog catalog almost full
13704         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13705         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13706
13707         for i in $(seq $MDSCOUNT); do
13708                 cl_users=(${CL_USERS[mds$i]})
13709                 cl_user1[mds$i]="${cl_users[0]}"
13710                 cl_user2[mds$i]="${cl_users[1]}"
13711
13712                 [ -n "${cl_user1[mds$i]}" ] ||
13713                         error "mds$i: no user registered"
13714                 [ -n "${cl_user2[mds$i]}" ] ||
13715                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13716
13717                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13718                 [ -n "$user_rec1" ] ||
13719                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13720                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13721                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13722                 [ -n "$user_rec2" ] ||
13723                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13724                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13725                      "$user_rec1 + 2 == $user_rec2"
13726                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13727                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13728                               "$user_rec1 + 2, but is $user_rec2"
13729                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13730                 [ -n "$user_rec2" ] ||
13731                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13732                 [ $user_rec1 == $user_rec2 ] ||
13733                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13734                               "$user_rec1, but is $user_rec2"
13735         done
13736
13737         # force cl_user2 to be idle (2nd part) and to reach
13738         # changelog_max_idle_time
13739         sleep 2
13740
13741         # generate one more changelog to trigger fail_loc
13742         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13743                 error "create $DIR/$tdir/${tfile}bis failed"
13744
13745         # ensure gc thread is done
13746         for i in $(mdts_nodes); do
13747                 wait_update $i \
13748                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13749                         error "$i: GC-thread not done"
13750         done
13751
13752         local first_rec
13753         for i in $(seq $MDSCOUNT); do
13754                 # check cl_user1 still registered
13755                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13756                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13757                 # check cl_user2 unregistered
13758                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13759                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13760
13761                 # check changelogs are present and starting at $user_rec1 + 1
13762                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13763                 [ -n "$user_rec1" ] ||
13764                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13765                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13766                             awk '{ print $1; exit; }')
13767
13768                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13769                 [ $((user_rec1 + 1)) == $first_rec ] ||
13770                         error "mds$i: first index should be $user_rec1 + 1, " \
13771                               "but is $first_rec"
13772         done
13773 }
13774 run_test 160f "changelog garbage collect (timestamped users)"
13775
13776 test_160g() {
13777         remote_mds_nodsh && skip "remote MDS with nodsh"
13778         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13779                 skip "Need MDS version at least 2.10.56"
13780
13781         local mdts=$(comma_list $(mdts_nodes))
13782
13783         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13784         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13785
13786         # Create a user
13787         changelog_register || error "first changelog_register failed"
13788         changelog_register || error "second changelog_register failed"
13789         local cl_users
13790         declare -A cl_user1
13791         declare -A cl_user2
13792         local user_rec1
13793         local user_rec2
13794         local i
13795
13796         # generate some changelog records to accumulate on each MDT
13797         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13798         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13799                 error "create $DIR/$tdir/$tfile failed"
13800
13801         # check changelogs have been generated
13802         local nbcl=$(changelog_dump | wc -l)
13803         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13804
13805         # reduce the max_idle_indexes value to make sure we exceed it
13806         max_ndx=$((nbcl / 2 - 1))
13807
13808         for param in "changelog_max_idle_indexes=$max_ndx" \
13809                      "changelog_gc=1" \
13810                      "changelog_min_gc_interval=2" \
13811                      "changelog_min_free_cat_entries=3"; do
13812                 local MDT0=$(facet_svc $SINGLEMDS)
13813                 local var="${param%=*}"
13814                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13815
13816                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13817                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13818                         error "unable to set mdd.*.$param"
13819         done
13820
13821         # simulate changelog catalog almost full
13822         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13823         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13824
13825         for i in $(seq $MDSCOUNT); do
13826                 cl_users=(${CL_USERS[mds$i]})
13827                 cl_user1[mds$i]="${cl_users[0]}"
13828                 cl_user2[mds$i]="${cl_users[1]}"
13829
13830                 [ -n "${cl_user1[mds$i]}" ] ||
13831                         error "mds$i: no user registered"
13832                 [ -n "${cl_user2[mds$i]}" ] ||
13833                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13834
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                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13839                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13840                 [ -n "$user_rec2" ] ||
13841                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13842                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13843                      "$user_rec1 + 2 == $user_rec2"
13844                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13845                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13846                               "$user_rec1 + 2, but is $user_rec2"
13847                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13848                 [ -n "$user_rec2" ] ||
13849                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13850                 [ $user_rec1 == $user_rec2 ] ||
13851                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13852                               "$user_rec1, but is $user_rec2"
13853         done
13854
13855         # ensure we are past the previous changelog_min_gc_interval set above
13856         sleep 2
13857
13858         # generate one more changelog to trigger fail_loc
13859         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13860                 error "create $DIR/$tdir/${tfile}bis failed"
13861
13862         # ensure gc thread is done
13863         for i in $(mdts_nodes); do
13864                 wait_update $i \
13865                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13866                         error "$i: GC-thread not done"
13867         done
13868
13869         local first_rec
13870         for i in $(seq $MDSCOUNT); do
13871                 # check cl_user1 still registered
13872                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13873                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13874                 # check cl_user2 unregistered
13875                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13876                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13877
13878                 # check changelogs are present and starting at $user_rec1 + 1
13879                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13880                 [ -n "$user_rec1" ] ||
13881                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13882                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13883                             awk '{ print $1; exit; }')
13884
13885                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13886                 [ $((user_rec1 + 1)) == $first_rec ] ||
13887                         error "mds$i: first index should be $user_rec1 + 1, " \
13888                               "but is $first_rec"
13889         done
13890 }
13891 run_test 160g "changelog garbage collect (old users)"
13892
13893 test_160h() {
13894         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13895         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13896                 skip "Need MDS version at least 2.10.56"
13897
13898         local mdts=$(comma_list $(mdts_nodes))
13899
13900         # Create a user
13901         changelog_register || error "first changelog_register failed"
13902         changelog_register || error "second changelog_register failed"
13903         local cl_users
13904         declare -A cl_user1
13905         declare -A cl_user2
13906         local user_rec1
13907         local user_rec2
13908         local i
13909
13910         # generate some changelog records to accumulate on each MDT
13911         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13912         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13913                 error "create $DIR/$tdir/$tfile failed"
13914
13915         # check changelogs have been generated
13916         local nbcl=$(changelog_dump | wc -l)
13917         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13918
13919         for param in "changelog_max_idle_time=10" \
13920                      "changelog_gc=1" \
13921                      "changelog_min_gc_interval=2"; do
13922                 local MDT0=$(facet_svc $SINGLEMDS)
13923                 local var="${param%=*}"
13924                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13925
13926                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13927                 do_nodes $mdts $LCTL set_param mdd.*.$param
13928         done
13929
13930         # force cl_user2 to be idle (1st part)
13931         sleep 9
13932
13933         for i in $(seq $MDSCOUNT); do
13934                 cl_users=(${CL_USERS[mds$i]})
13935                 cl_user1[mds$i]="${cl_users[0]}"
13936                 cl_user2[mds$i]="${cl_users[1]}"
13937
13938                 [ -n "${cl_user1[mds$i]}" ] ||
13939                         error "mds$i: no user registered"
13940                 [ -n "${cl_user2[mds$i]}" ] ||
13941                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13942
13943                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13944                 [ -n "$user_rec1" ] ||
13945                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13946                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13947                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13948                 [ -n "$user_rec2" ] ||
13949                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13950                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13951                      "$user_rec1 + 2 == $user_rec2"
13952                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13953                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13954                               "$user_rec1 + 2, but is $user_rec2"
13955                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13956                 [ -n "$user_rec2" ] ||
13957                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13958                 [ $user_rec1 == $user_rec2 ] ||
13959                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13960                               "$user_rec1, but is $user_rec2"
13961         done
13962
13963         # force cl_user2 to be idle (2nd part) and to reach
13964         # changelog_max_idle_time
13965         sleep 2
13966
13967         # force each GC-thread start and block then
13968         # one per MDT/MDD, set fail_val accordingly
13969         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
13970         do_nodes $mdts $LCTL set_param fail_loc=0x1316
13971
13972         # generate more changelogs to trigger fail_loc
13973         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13974                 error "create $DIR/$tdir/${tfile}bis failed"
13975
13976         # stop MDT to stop GC-thread, should be done in back-ground as it will
13977         # block waiting for the thread to be released and exit
13978         declare -A stop_pids
13979         for i in $(seq $MDSCOUNT); do
13980                 stop mds$i &
13981                 stop_pids[mds$i]=$!
13982         done
13983
13984         for i in $(mdts_nodes); do
13985                 local facet
13986                 local nb=0
13987                 local facets=$(facets_up_on_host $i)
13988
13989                 for facet in ${facets//,/ }; do
13990                         if [[ $facet == mds* ]]; then
13991                                 nb=$((nb + 1))
13992                         fi
13993                 done
13994                 # ensure each MDS's gc threads are still present and all in "R"
13995                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
13996                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
13997                         error "$i: expected $nb GC-thread"
13998                 wait_update $i \
13999                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14000                         "R" 20 ||
14001                         error "$i: GC-thread not found in R-state"
14002                 # check umounts of each MDT on MDS have reached kthread_stop()
14003                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14004                         error "$i: expected $nb umount"
14005                 wait_update $i \
14006                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14007                         error "$i: umount not found in D-state"
14008         done
14009
14010         # release all GC-threads
14011         do_nodes $mdts $LCTL set_param fail_loc=0
14012
14013         # wait for MDT stop to complete
14014         for i in $(seq $MDSCOUNT); do
14015                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14016         done
14017
14018         # XXX
14019         # may try to check if any orphan changelog records are present
14020         # via ldiskfs/zfs and llog_reader...
14021
14022         # re-start/mount MDTs
14023         for i in $(seq $MDSCOUNT); do
14024                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14025                         error "Fail to start mds$i"
14026         done
14027
14028         local first_rec
14029         for i in $(seq $MDSCOUNT); do
14030                 # check cl_user1 still registered
14031                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14032                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14033                 # check cl_user2 unregistered
14034                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14035                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14036
14037                 # check changelogs are present and starting at $user_rec1 + 1
14038                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14039                 [ -n "$user_rec1" ] ||
14040                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14041                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14042                             awk '{ print $1; exit; }')
14043
14044                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14045                 [ $((user_rec1 + 1)) == $first_rec ] ||
14046                         error "mds$i: first index should be $user_rec1 + 1, " \
14047                               "but is $first_rec"
14048         done
14049 }
14050 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14051               "during mount"
14052
14053 test_160i() {
14054
14055         local mdts=$(comma_list $(mdts_nodes))
14056
14057         changelog_register || error "first changelog_register failed"
14058
14059         # generate some changelog records to accumulate on each MDT
14060         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14061         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14062                 error "create $DIR/$tdir/$tfile failed"
14063
14064         # check changelogs have been generated
14065         local nbcl=$(changelog_dump | wc -l)
14066         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14067
14068         # simulate race between register and unregister
14069         # XXX as fail_loc is set per-MDS, with DNE configs the race
14070         # simulation will only occur for one MDT per MDS and for the
14071         # others the normal race scenario will take place
14072         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14073         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14074         do_nodes $mdts $LCTL set_param fail_val=1
14075
14076         # unregister 1st user
14077         changelog_deregister &
14078         local pid1=$!
14079         # wait some time for deregister work to reach race rdv
14080         sleep 2
14081         # register 2nd user
14082         changelog_register || error "2nd user register failed"
14083
14084         wait $pid1 || error "1st user deregister failed"
14085
14086         local i
14087         local last_rec
14088         declare -A LAST_REC
14089         for i in $(seq $MDSCOUNT); do
14090                 if changelog_users mds$i | grep "^cl"; then
14091                         # make sure new records are added with one user present
14092                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14093                                           awk '/^current.index:/ { print $NF }')
14094                 else
14095                         error "mds$i has no user registered"
14096                 fi
14097         done
14098
14099         # generate more changelog records to accumulate on each MDT
14100         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14101                 error "create $DIR/$tdir/${tfile}bis failed"
14102
14103         for i in $(seq $MDSCOUNT); do
14104                 last_rec=$(changelog_users $SINGLEMDS |
14105                            awk '/^current.index:/ { print $NF }')
14106                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14107                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14108                         error "changelogs are off on mds$i"
14109         done
14110 }
14111 run_test 160i "changelog user register/unregister race"
14112
14113 test_160j() {
14114         remote_mds_nodsh && skip "remote MDS with nodsh"
14115         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14116                 skip "Need MDS version at least 2.12.56"
14117
14118         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14119
14120         changelog_register || error "first changelog_register failed"
14121
14122         # generate some changelog
14123         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14124         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14125                 error "create $DIR/$tdir/${tfile}bis failed"
14126
14127         # open the changelog device
14128         exec 3>/dev/changelog-$FSNAME-MDT0000
14129         exec 4</dev/changelog-$FSNAME-MDT0000
14130
14131         # umount the first lustre mount
14132         umount $MOUNT
14133
14134         # read changelog
14135         cat <&4 >/dev/null || error "read changelog failed"
14136
14137         # clear changelog
14138         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14139         changelog_users $SINGLEMDS | grep -q $cl_user ||
14140                 error "User $cl_user not found in changelog_users"
14141
14142         printf 'clear:'$cl_user':0' >&3
14143
14144         # close
14145         exec 3>&-
14146         exec 4<&-
14147
14148         # cleanup
14149         changelog_deregister || error "changelog_deregister failed"
14150
14151         umount $MOUNT2
14152         mount_client $MOUNT || error "mount_client on $MOUNT failed"
14153 }
14154 run_test 160j "client can be umounted  while its chanangelog is being used"
14155
14156 test_160k() {
14157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14158         remote_mds_nodsh && skip "remote MDS with nodsh"
14159
14160         mkdir -p $DIR/$tdir/1/1
14161
14162         changelog_register || error "changelog_register failed"
14163         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14164
14165         changelog_users $SINGLEMDS | grep -q $cl_user ||
14166                 error "User '$cl_user' not found in changelog_users"
14167 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14168         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14169         rmdir $DIR/$tdir/1/1 & sleep 1
14170         mkdir $DIR/$tdir/2
14171         touch $DIR/$tdir/2/2
14172         rm -rf $DIR/$tdir/2
14173
14174         wait
14175         sleep 4
14176
14177         changelog_dump | grep rmdir || error "rmdir not recorded"
14178
14179         rm -rf $DIR/$tdir
14180         changelog_deregister
14181 }
14182 run_test 160k "Verify that changelog records are not lost"
14183
14184 test_161a() {
14185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14186
14187         test_mkdir -c1 $DIR/$tdir
14188         cp /etc/hosts $DIR/$tdir/$tfile
14189         test_mkdir -c1 $DIR/$tdir/foo1
14190         test_mkdir -c1 $DIR/$tdir/foo2
14191         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14192         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14193         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14194         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14195         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14196         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14197                 $LFS fid2path $DIR $FID
14198                 error "bad link ea"
14199         fi
14200         # middle
14201         rm $DIR/$tdir/foo2/zachary
14202         # last
14203         rm $DIR/$tdir/foo2/thor
14204         # first
14205         rm $DIR/$tdir/$tfile
14206         # rename
14207         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
14208         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
14209                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
14210         rm $DIR/$tdir/foo2/maggie
14211
14212         # overflow the EA
14213         local longname=$tfile.avg_len_is_thirty_two_
14214         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
14215                 error_noexit 'failed to unlink many hardlinks'" EXIT
14216         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
14217                 error "failed to hardlink many files"
14218         links=$($LFS fid2path $DIR $FID | wc -l)
14219         echo -n "${links}/1000 links in link EA"
14220         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
14221 }
14222 run_test 161a "link ea sanity"
14223
14224 test_161b() {
14225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14226         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
14227
14228         local MDTIDX=1
14229         local remote_dir=$DIR/$tdir/remote_dir
14230
14231         mkdir -p $DIR/$tdir
14232         $LFS mkdir -i $MDTIDX $remote_dir ||
14233                 error "create remote directory failed"
14234
14235         cp /etc/hosts $remote_dir/$tfile
14236         mkdir -p $remote_dir/foo1
14237         mkdir -p $remote_dir/foo2
14238         ln $remote_dir/$tfile $remote_dir/foo1/sofia
14239         ln $remote_dir/$tfile $remote_dir/foo2/zachary
14240         ln $remote_dir/$tfile $remote_dir/foo1/luna
14241         ln $remote_dir/$tfile $remote_dir/foo2/thor
14242
14243         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
14244                      tr -d ']')
14245         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14246                 $LFS fid2path $DIR $FID
14247                 error "bad link ea"
14248         fi
14249         # middle
14250         rm $remote_dir/foo2/zachary
14251         # last
14252         rm $remote_dir/foo2/thor
14253         # first
14254         rm $remote_dir/$tfile
14255         # rename
14256         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
14257         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
14258         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
14259                 $LFS fid2path $DIR $FID
14260                 error "bad link rename"
14261         fi
14262         rm $remote_dir/foo2/maggie
14263
14264         # overflow the EA
14265         local longname=filename_avg_len_is_thirty_two_
14266         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
14267                 error "failed to hardlink many files"
14268         links=$($LFS fid2path $DIR $FID | wc -l)
14269         echo -n "${links}/1000 links in link EA"
14270         [[ ${links} -gt 60 ]] ||
14271                 error "expected at least 60 links in link EA"
14272         unlinkmany $remote_dir/foo2/$longname 1000 ||
14273         error "failed to unlink many hardlinks"
14274 }
14275 run_test 161b "link ea sanity under remote directory"
14276
14277 test_161c() {
14278         remote_mds_nodsh && skip "remote MDS with nodsh"
14279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14280         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
14281                 skip "Need MDS version at least 2.1.5"
14282
14283         # define CLF_RENAME_LAST 0x0001
14284         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
14285         changelog_register || error "changelog_register failed"
14286
14287         rm -rf $DIR/$tdir
14288         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
14289         touch $DIR/$tdir/foo_161c
14290         touch $DIR/$tdir/bar_161c
14291         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14292         changelog_dump | grep RENME | tail -n 5
14293         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14294         changelog_clear 0 || error "changelog_clear failed"
14295         if [ x$flags != "x0x1" ]; then
14296                 error "flag $flags is not 0x1"
14297         fi
14298
14299         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
14300         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
14301         touch $DIR/$tdir/foo_161c
14302         touch $DIR/$tdir/bar_161c
14303         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14304         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14305         changelog_dump | grep RENME | tail -n 5
14306         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14307         changelog_clear 0 || error "changelog_clear failed"
14308         if [ x$flags != "x0x0" ]; then
14309                 error "flag $flags is not 0x0"
14310         fi
14311         echo "rename overwrite a target having nlink > 1," \
14312                 "changelog record has flags of $flags"
14313
14314         # rename doesn't overwrite a target (changelog flag 0x0)
14315         touch $DIR/$tdir/foo_161c
14316         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
14317         changelog_dump | grep RENME | tail -n 5
14318         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
14319         changelog_clear 0 || error "changelog_clear failed"
14320         if [ x$flags != "x0x0" ]; then
14321                 error "flag $flags is not 0x0"
14322         fi
14323         echo "rename doesn't overwrite a target," \
14324                 "changelog record has flags of $flags"
14325
14326         # define CLF_UNLINK_LAST 0x0001
14327         # unlink a file having nlink = 1 (changelog flag 0x1)
14328         rm -f $DIR/$tdir/foo2_161c
14329         changelog_dump | grep UNLNK | tail -n 5
14330         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14331         changelog_clear 0 || error "changelog_clear failed"
14332         if [ x$flags != "x0x1" ]; then
14333                 error "flag $flags is not 0x1"
14334         fi
14335         echo "unlink a file having nlink = 1," \
14336                 "changelog record has flags of $flags"
14337
14338         # unlink a file having nlink > 1 (changelog flag 0x0)
14339         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14340         rm -f $DIR/$tdir/foobar_161c
14341         changelog_dump | grep UNLNK | tail -n 5
14342         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14343         changelog_clear 0 || error "changelog_clear failed"
14344         if [ x$flags != "x0x0" ]; then
14345                 error "flag $flags is not 0x0"
14346         fi
14347         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
14348 }
14349 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
14350
14351 test_161d() {
14352         remote_mds_nodsh && skip "remote MDS with nodsh"
14353         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
14354
14355         local pid
14356         local fid
14357
14358         changelog_register || error "changelog_register failed"
14359
14360         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
14361         # interfer with $MOUNT/.lustre/fid/ access
14362         mkdir $DIR/$tdir
14363         [[ $? -eq 0 ]] || error "mkdir failed"
14364
14365         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
14366         $LCTL set_param fail_loc=0x8000140c
14367         # 5s pause
14368         $LCTL set_param fail_val=5
14369
14370         # create file
14371         echo foofoo > $DIR/$tdir/$tfile &
14372         pid=$!
14373
14374         # wait for create to be delayed
14375         sleep 2
14376
14377         ps -p $pid
14378         [[ $? -eq 0 ]] || error "create should be blocked"
14379
14380         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
14381         stack_trap "rm -f $tempfile"
14382         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
14383         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
14384         # some delay may occur during ChangeLog publishing and file read just
14385         # above, that could allow file write to happen finally
14386         [[ -s $tempfile ]] && echo "file should be empty"
14387
14388         $LCTL set_param fail_loc=0
14389
14390         wait $pid
14391         [[ $? -eq 0 ]] || error "create failed"
14392 }
14393 run_test 161d "create with concurrent .lustre/fid access"
14394
14395 check_path() {
14396         local expected="$1"
14397         shift
14398         local fid="$2"
14399
14400         local path
14401         path=$($LFS fid2path "$@")
14402         local rc=$?
14403
14404         if [ $rc -ne 0 ]; then
14405                 error "path looked up of '$expected' failed: rc=$rc"
14406         elif [ "$path" != "$expected" ]; then
14407                 error "path looked up '$path' instead of '$expected'"
14408         else
14409                 echo "FID '$fid' resolves to path '$path' as expected"
14410         fi
14411 }
14412
14413 test_162a() { # was test_162
14414         test_mkdir -p -c1 $DIR/$tdir/d2
14415         touch $DIR/$tdir/d2/$tfile
14416         touch $DIR/$tdir/d2/x1
14417         touch $DIR/$tdir/d2/x2
14418         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
14419         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
14420         # regular file
14421         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
14422         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
14423
14424         # softlink
14425         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
14426         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
14427         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
14428
14429         # softlink to wrong file
14430         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
14431         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
14432         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
14433
14434         # hardlink
14435         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
14436         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
14437         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
14438         # fid2path dir/fsname should both work
14439         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
14440         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
14441
14442         # hardlink count: check that there are 2 links
14443         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
14444         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
14445
14446         # hardlink indexing: remove the first link
14447         rm $DIR/$tdir/d2/p/q/r/hlink
14448         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
14449 }
14450 run_test 162a "path lookup sanity"
14451
14452 test_162b() {
14453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14454         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14455
14456         mkdir $DIR/$tdir
14457         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
14458                                 error "create striped dir failed"
14459
14460         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
14461                                         tail -n 1 | awk '{print $2}')
14462         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
14463
14464         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
14465         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
14466
14467         # regular file
14468         for ((i=0;i<5;i++)); do
14469                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
14470                         error "get fid for f$i failed"
14471                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
14472
14473                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
14474                         error "get fid for d$i failed"
14475                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
14476         done
14477
14478         return 0
14479 }
14480 run_test 162b "striped directory path lookup sanity"
14481
14482 # LU-4239: Verify fid2path works with paths 100 or more directories deep
14483 test_162c() {
14484         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
14485                 skip "Need MDS version at least 2.7.51"
14486
14487         local lpath=$tdir.local
14488         local rpath=$tdir.remote
14489
14490         test_mkdir $DIR/$lpath
14491         test_mkdir $DIR/$rpath
14492
14493         for ((i = 0; i <= 101; i++)); do
14494                 lpath="$lpath/$i"
14495                 mkdir $DIR/$lpath
14496                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
14497                         error "get fid for local directory $DIR/$lpath failed"
14498                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
14499
14500                 rpath="$rpath/$i"
14501                 test_mkdir $DIR/$rpath
14502                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
14503                         error "get fid for remote directory $DIR/$rpath failed"
14504                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
14505         done
14506
14507         return 0
14508 }
14509 run_test 162c "fid2path works with paths 100 or more directories deep"
14510
14511 test_169() {
14512         # do directio so as not to populate the page cache
14513         log "creating a 10 Mb file"
14514         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14515         log "starting reads"
14516         dd if=$DIR/$tfile of=/dev/null bs=4096 &
14517         log "truncating the file"
14518         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14519         log "killing dd"
14520         kill %+ || true # reads might have finished
14521         echo "wait until dd is finished"
14522         wait
14523         log "removing the temporary file"
14524         rm -rf $DIR/$tfile || error "tmp file removal failed"
14525 }
14526 run_test 169 "parallel read and truncate should not deadlock"
14527
14528 test_170() {
14529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14530
14531         $LCTL clear     # bug 18514
14532         $LCTL debug_daemon start $TMP/${tfile}_log_good
14533         touch $DIR/$tfile
14534         $LCTL debug_daemon stop
14535         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
14536                 error "sed failed to read log_good"
14537
14538         $LCTL debug_daemon start $TMP/${tfile}_log_good
14539         rm -rf $DIR/$tfile
14540         $LCTL debug_daemon stop
14541
14542         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
14543                error "lctl df log_bad failed"
14544
14545         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14546         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14547
14548         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
14549         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
14550
14551         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
14552                 error "bad_line good_line1 good_line2 are empty"
14553
14554         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14555         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14556         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14557
14558         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14559         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14560         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14561
14562         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14563                 error "bad_line_new good_line_new are empty"
14564
14565         local expected_good=$((good_line1 + good_line2*2))
14566
14567         rm -f $TMP/${tfile}*
14568         # LU-231, short malformed line may not be counted into bad lines
14569         if [ $bad_line -ne $bad_line_new ] &&
14570                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14571                 error "expected $bad_line bad lines, but got $bad_line_new"
14572                 return 1
14573         fi
14574
14575         if [ $expected_good -ne $good_line_new ]; then
14576                 error "expected $expected_good good lines, but got $good_line_new"
14577                 return 2
14578         fi
14579         true
14580 }
14581 run_test 170 "test lctl df to handle corrupted log ====================="
14582
14583 test_171() { # bug20592
14584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14585
14586         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
14587         $LCTL set_param fail_loc=0x50e
14588         $LCTL set_param fail_val=3000
14589         multiop_bg_pause $DIR/$tfile O_s || true
14590         local MULTIPID=$!
14591         kill -USR1 $MULTIPID
14592         # cause log dump
14593         sleep 3
14594         wait $MULTIPID
14595         if dmesg | grep "recursive fault"; then
14596                 error "caught a recursive fault"
14597         fi
14598         $LCTL set_param fail_loc=0
14599         true
14600 }
14601 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
14602
14603 # it would be good to share it with obdfilter-survey/iokit-libecho code
14604 setup_obdecho_osc () {
14605         local rc=0
14606         local ost_nid=$1
14607         local obdfilter_name=$2
14608         echo "Creating new osc for $obdfilter_name on $ost_nid"
14609         # make sure we can find loopback nid
14610         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
14611
14612         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
14613                            ${obdfilter_name}_osc_UUID || rc=2; }
14614         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
14615                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
14616         return $rc
14617 }
14618
14619 cleanup_obdecho_osc () {
14620         local obdfilter_name=$1
14621         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14622         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14623         return 0
14624 }
14625
14626 obdecho_test() {
14627         local OBD=$1
14628         local node=$2
14629         local pages=${3:-64}
14630         local rc=0
14631         local id
14632
14633         local count=10
14634         local obd_size=$(get_obd_size $node $OBD)
14635         local page_size=$(get_page_size $node)
14636         if [[ -n "$obd_size" ]]; then
14637                 local new_count=$((obd_size / (pages * page_size / 1024)))
14638                 [[ $new_count -ge $count ]] || count=$new_count
14639         fi
14640
14641         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14642         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14643                            rc=2; }
14644         if [ $rc -eq 0 ]; then
14645             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14646             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14647         fi
14648         echo "New object id is $id"
14649         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14650                            rc=4; }
14651         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14652                            "test_brw $count w v $pages $id" || rc=4; }
14653         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14654                            rc=4; }
14655         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14656                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14657         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14658                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14659         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14660         return $rc
14661 }
14662
14663 test_180a() {
14664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14665
14666         if ! module_loaded obdecho; then
14667                 load_module obdecho/obdecho &&
14668                         stack_trap "rmmod obdecho" EXIT ||
14669                         error "unable to load obdecho on client"
14670         fi
14671
14672         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14673         local host=$($LCTL get_param -n osc.$osc.import |
14674                      awk '/current_connection:/ { print $2 }' )
14675         local target=$($LCTL get_param -n osc.$osc.import |
14676                        awk '/target:/ { print $2 }' )
14677         target=${target%_UUID}
14678
14679         if [ -n "$target" ]; then
14680                 setup_obdecho_osc $host $target &&
14681                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14682                         { error "obdecho setup failed with $?"; return; }
14683
14684                 obdecho_test ${target}_osc client ||
14685                         error "obdecho_test failed on ${target}_osc"
14686         else
14687                 $LCTL get_param osc.$osc.import
14688                 error "there is no osc.$osc.import target"
14689         fi
14690 }
14691 run_test 180a "test obdecho on osc"
14692
14693 test_180b() {
14694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14695         remote_ost_nodsh && skip "remote OST with nodsh"
14696
14697         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14698                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14699                 error "failed to load module obdecho"
14700
14701         local target=$(do_facet ost1 $LCTL dl |
14702                        awk '/obdfilter/ { print $4; exit; }')
14703
14704         if [ -n "$target" ]; then
14705                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14706         else
14707                 do_facet ost1 $LCTL dl
14708                 error "there is no obdfilter target on ost1"
14709         fi
14710 }
14711 run_test 180b "test obdecho directly on obdfilter"
14712
14713 test_180c() { # LU-2598
14714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14715         remote_ost_nodsh && skip "remote OST with nodsh"
14716         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14717                 skip "Need MDS version at least 2.4.0"
14718
14719         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14720                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14721                 error "failed to load module obdecho"
14722
14723         local target=$(do_facet ost1 $LCTL dl |
14724                        awk '/obdfilter/ { print $4; exit; }')
14725
14726         if [ -n "$target" ]; then
14727                 local pages=16384 # 64MB bulk I/O RPC size
14728
14729                 obdecho_test "$target" ost1 "$pages" ||
14730                         error "obdecho_test with pages=$pages failed with $?"
14731         else
14732                 do_facet ost1 $LCTL dl
14733                 error "there is no obdfilter target on ost1"
14734         fi
14735 }
14736 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14737
14738 test_181() { # bug 22177
14739         test_mkdir $DIR/$tdir
14740         # create enough files to index the directory
14741         createmany -o $DIR/$tdir/foobar 4000
14742         # print attributes for debug purpose
14743         lsattr -d .
14744         # open dir
14745         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14746         MULTIPID=$!
14747         # remove the files & current working dir
14748         unlinkmany $DIR/$tdir/foobar 4000
14749         rmdir $DIR/$tdir
14750         kill -USR1 $MULTIPID
14751         wait $MULTIPID
14752         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14753         return 0
14754 }
14755 run_test 181 "Test open-unlinked dir ========================"
14756
14757 test_182() {
14758         local fcount=1000
14759         local tcount=10
14760
14761         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14762
14763         $LCTL set_param mdc.*.rpc_stats=clear
14764
14765         for (( i = 0; i < $tcount; i++ )) ; do
14766                 mkdir $DIR/$tdir/$i
14767         done
14768
14769         for (( i = 0; i < $tcount; i++ )) ; do
14770                 createmany -o $DIR/$tdir/$i/f- $fcount &
14771         done
14772         wait
14773
14774         for (( i = 0; i < $tcount; i++ )) ; do
14775                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14776         done
14777         wait
14778
14779         $LCTL get_param mdc.*.rpc_stats
14780
14781         rm -rf $DIR/$tdir
14782 }
14783 run_test 182 "Test parallel modify metadata operations ================"
14784
14785 test_183() { # LU-2275
14786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14787         remote_mds_nodsh && skip "remote MDS with nodsh"
14788         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14789                 skip "Need MDS version at least 2.3.56"
14790
14791         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14792         echo aaa > $DIR/$tdir/$tfile
14793
14794 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14795         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14796
14797         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14798         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14799
14800         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14801
14802         # Flush negative dentry cache
14803         touch $DIR/$tdir/$tfile
14804
14805         # We are not checking for any leaked references here, they'll
14806         # become evident next time we do cleanup with module unload.
14807         rm -rf $DIR/$tdir
14808 }
14809 run_test 183 "No crash or request leak in case of strange dispositions ========"
14810
14811 # test suite 184 is for LU-2016, LU-2017
14812 test_184a() {
14813         check_swap_layouts_support
14814
14815         dir0=$DIR/$tdir/$testnum
14816         test_mkdir -p -c1 $dir0
14817         ref1=/etc/passwd
14818         ref2=/etc/group
14819         file1=$dir0/f1
14820         file2=$dir0/f2
14821         $LFS setstripe -c1 $file1
14822         cp $ref1 $file1
14823         $LFS setstripe -c2 $file2
14824         cp $ref2 $file2
14825         gen1=$($LFS getstripe -g $file1)
14826         gen2=$($LFS getstripe -g $file2)
14827
14828         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14829         gen=$($LFS getstripe -g $file1)
14830         [[ $gen1 != $gen ]] ||
14831                 "Layout generation on $file1 does not change"
14832         gen=$($LFS getstripe -g $file2)
14833         [[ $gen2 != $gen ]] ||
14834                 "Layout generation on $file2 does not change"
14835
14836         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14837         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14838
14839         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14840 }
14841 run_test 184a "Basic layout swap"
14842
14843 test_184b() {
14844         check_swap_layouts_support
14845
14846         dir0=$DIR/$tdir/$testnum
14847         mkdir -p $dir0 || error "creating dir $dir0"
14848         file1=$dir0/f1
14849         file2=$dir0/f2
14850         file3=$dir0/f3
14851         dir1=$dir0/d1
14852         dir2=$dir0/d2
14853         mkdir $dir1 $dir2
14854         $LFS setstripe -c1 $file1
14855         $LFS setstripe -c2 $file2
14856         $LFS setstripe -c1 $file3
14857         chown $RUNAS_ID $file3
14858         gen1=$($LFS getstripe -g $file1)
14859         gen2=$($LFS getstripe -g $file2)
14860
14861         $LFS swap_layouts $dir1 $dir2 &&
14862                 error "swap of directories layouts should fail"
14863         $LFS swap_layouts $dir1 $file1 &&
14864                 error "swap of directory and file layouts should fail"
14865         $RUNAS $LFS swap_layouts $file1 $file2 &&
14866                 error "swap of file we cannot write should fail"
14867         $LFS swap_layouts $file1 $file3 &&
14868                 error "swap of file with different owner should fail"
14869         /bin/true # to clear error code
14870 }
14871 run_test 184b "Forbidden layout swap (will generate errors)"
14872
14873 test_184c() {
14874         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14875         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14876         check_swap_layouts_support
14877
14878         local dir0=$DIR/$tdir/$testnum
14879         mkdir -p $dir0 || error "creating dir $dir0"
14880
14881         local ref1=$dir0/ref1
14882         local ref2=$dir0/ref2
14883         local file1=$dir0/file1
14884         local file2=$dir0/file2
14885         # create a file large enough for the concurrent test
14886         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14887         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14888         echo "ref file size: ref1($(stat -c %s $ref1))," \
14889              "ref2($(stat -c %s $ref2))"
14890
14891         cp $ref2 $file2
14892         dd if=$ref1 of=$file1 bs=16k &
14893         local DD_PID=$!
14894
14895         # Make sure dd starts to copy file
14896         while [ ! -f $file1 ]; do sleep 0.1; done
14897
14898         $LFS swap_layouts $file1 $file2
14899         local rc=$?
14900         wait $DD_PID
14901         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14902         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14903
14904         # how many bytes copied before swapping layout
14905         local copied=$(stat -c %s $file2)
14906         local remaining=$(stat -c %s $ref1)
14907         remaining=$((remaining - copied))
14908         echo "Copied $copied bytes before swapping layout..."
14909
14910         cmp -n $copied $file1 $ref2 | grep differ &&
14911                 error "Content mismatch [0, $copied) of ref2 and file1"
14912         cmp -n $copied $file2 $ref1 ||
14913                 error "Content mismatch [0, $copied) of ref1 and file2"
14914         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14915                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14916
14917         # clean up
14918         rm -f $ref1 $ref2 $file1 $file2
14919 }
14920 run_test 184c "Concurrent write and layout swap"
14921
14922 test_184d() {
14923         check_swap_layouts_support
14924         [ -z "$(which getfattr 2>/dev/null)" ] &&
14925                 skip_env "no getfattr command"
14926
14927         local file1=$DIR/$tdir/$tfile-1
14928         local file2=$DIR/$tdir/$tfile-2
14929         local file3=$DIR/$tdir/$tfile-3
14930         local lovea1
14931         local lovea2
14932
14933         mkdir -p $DIR/$tdir
14934         touch $file1 || error "create $file1 failed"
14935         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14936                 error "create $file2 failed"
14937         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14938                 error "create $file3 failed"
14939         lovea1=$(get_layout_param $file1)
14940
14941         $LFS swap_layouts $file2 $file3 ||
14942                 error "swap $file2 $file3 layouts failed"
14943         $LFS swap_layouts $file1 $file2 ||
14944                 error "swap $file1 $file2 layouts failed"
14945
14946         lovea2=$(get_layout_param $file2)
14947         echo "$lovea1"
14948         echo "$lovea2"
14949         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14950
14951         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14952         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14953 }
14954 run_test 184d "allow stripeless layouts swap"
14955
14956 test_184e() {
14957         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14958                 skip "Need MDS version at least 2.6.94"
14959         check_swap_layouts_support
14960         [ -z "$(which getfattr 2>/dev/null)" ] &&
14961                 skip_env "no getfattr command"
14962
14963         local file1=$DIR/$tdir/$tfile-1
14964         local file2=$DIR/$tdir/$tfile-2
14965         local file3=$DIR/$tdir/$tfile-3
14966         local lovea
14967
14968         mkdir -p $DIR/$tdir
14969         touch $file1 || error "create $file1 failed"
14970         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14971                 error "create $file2 failed"
14972         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14973                 error "create $file3 failed"
14974
14975         $LFS swap_layouts $file1 $file2 ||
14976                 error "swap $file1 $file2 layouts failed"
14977
14978         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14979         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
14980
14981         echo 123 > $file1 || error "Should be able to write into $file1"
14982
14983         $LFS swap_layouts $file1 $file3 ||
14984                 error "swap $file1 $file3 layouts failed"
14985
14986         echo 123 > $file1 || error "Should be able to write into $file1"
14987
14988         rm -rf $file1 $file2 $file3
14989 }
14990 run_test 184e "Recreate layout after stripeless layout swaps"
14991
14992 test_184f() {
14993         # Create a file with name longer than sizeof(struct stat) ==
14994         # 144 to see if we can get chars from the file name to appear
14995         # in the returned striping. Note that 'f' == 0x66.
14996         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
14997
14998         mkdir -p $DIR/$tdir
14999         mcreate $DIR/$tdir/$file
15000         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
15001                 error "IOC_MDC_GETFILEINFO returned garbage striping"
15002         fi
15003 }
15004 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
15005
15006 test_185() { # LU-2441
15007         # LU-3553 - no volatile file support in old servers
15008         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
15009                 skip "Need MDS version at least 2.3.60"
15010
15011         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15012         touch $DIR/$tdir/spoo
15013         local mtime1=$(stat -c "%Y" $DIR/$tdir)
15014         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
15015                 error "cannot create/write a volatile file"
15016         [ "$FILESET" == "" ] &&
15017         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
15018                 error "FID is still valid after close"
15019
15020         multiop_bg_pause $DIR/$tdir vVw4096_c
15021         local multi_pid=$!
15022
15023         local OLD_IFS=$IFS
15024         IFS=":"
15025         local fidv=($fid)
15026         IFS=$OLD_IFS
15027         # assume that the next FID for this client is sequential, since stdout
15028         # is unfortunately eaten by multiop_bg_pause
15029         local n=$((${fidv[1]} + 1))
15030         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
15031         if [ "$FILESET" == "" ]; then
15032                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
15033                         error "FID is missing before close"
15034         fi
15035         kill -USR1 $multi_pid
15036         # 1 second delay, so if mtime change we will see it
15037         sleep 1
15038         local mtime2=$(stat -c "%Y" $DIR/$tdir)
15039         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
15040 }
15041 run_test 185 "Volatile file support"
15042
15043 function create_check_volatile() {
15044         local idx=$1
15045         local tgt
15046
15047         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
15048         local PID=$!
15049         sleep 1
15050         local FID=$(cat /tmp/${tfile}.fid)
15051         [ "$FID" == "" ] && error "can't get FID for volatile"
15052         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
15053         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
15054         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
15055         kill -USR1 $PID
15056         wait
15057         sleep 1
15058         cancel_lru_locks mdc # flush opencache
15059         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
15060         return 0
15061 }
15062
15063 test_185a(){
15064         # LU-12516 - volatile creation via .lustre
15065         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
15066                 skip "Need MDS version at least 2.3.55"
15067
15068         create_check_volatile 0
15069         [ $MDSCOUNT -lt 2 ] && return 0
15070
15071         # DNE case
15072         create_check_volatile 1
15073
15074         return 0
15075 }
15076 run_test 185a "Volatile file creation in .lustre/fid/"
15077
15078 test_187a() {
15079         remote_mds_nodsh && skip "remote MDS with nodsh"
15080         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15081                 skip "Need MDS version at least 2.3.0"
15082
15083         local dir0=$DIR/$tdir/$testnum
15084         mkdir -p $dir0 || error "creating dir $dir0"
15085
15086         local file=$dir0/file1
15087         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
15088         local dv1=$($LFS data_version $file)
15089         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
15090         local dv2=$($LFS data_version $file)
15091         [[ $dv1 != $dv2 ]] ||
15092                 error "data version did not change on write $dv1 == $dv2"
15093
15094         # clean up
15095         rm -f $file1
15096 }
15097 run_test 187a "Test data version change"
15098
15099 test_187b() {
15100         remote_mds_nodsh && skip "remote MDS with nodsh"
15101         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15102                 skip "Need MDS version at least 2.3.0"
15103
15104         local dir0=$DIR/$tdir/$testnum
15105         mkdir -p $dir0 || error "creating dir $dir0"
15106
15107         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
15108         [[ ${DV[0]} != ${DV[1]} ]] ||
15109                 error "data version did not change on write"\
15110                       " ${DV[0]} == ${DV[1]}"
15111
15112         # clean up
15113         rm -f $file1
15114 }
15115 run_test 187b "Test data version change on volatile file"
15116
15117 test_200() {
15118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15119         remote_mgs_nodsh && skip "remote MGS with nodsh"
15120         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15121
15122         local POOL=${POOL:-cea1}
15123         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
15124         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
15125         # Pool OST targets
15126         local first_ost=0
15127         local last_ost=$(($OSTCOUNT - 1))
15128         local ost_step=2
15129         local ost_list=$(seq $first_ost $ost_step $last_ost)
15130         local ost_range="$first_ost $last_ost $ost_step"
15131         local test_path=$POOL_ROOT/$POOL_DIR_NAME
15132         local file_dir=$POOL_ROOT/file_tst
15133         local subdir=$test_path/subdir
15134         local rc=0
15135
15136         while : ; do
15137                 # former test_200a test_200b
15138                 pool_add $POOL                          || { rc=$? ; break; }
15139                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
15140                 # former test_200c test_200d
15141                 mkdir -p $test_path
15142                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
15143                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
15144                 mkdir -p $subdir
15145                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
15146                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
15147                                                         || { rc=$? ; break; }
15148                 # former test_200e test_200f
15149                 local files=$((OSTCOUNT*3))
15150                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
15151                                                         || { rc=$? ; break; }
15152                 pool_create_files $POOL $file_dir $files "$ost_list" \
15153                                                         || { rc=$? ; break; }
15154                 # former test_200g test_200h
15155                 pool_lfs_df $POOL                       || { rc=$? ; break; }
15156                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
15157
15158                 # former test_201a test_201b test_201c
15159                 pool_remove_first_target $POOL          || { rc=$? ; break; }
15160
15161                 local f=$test_path/$tfile
15162                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
15163                 pool_remove $POOL $f                    || { rc=$? ; break; }
15164                 break
15165         done
15166
15167         destroy_test_pools
15168
15169         return $rc
15170 }
15171 run_test 200 "OST pools"
15172
15173 # usage: default_attr <count | size | offset>
15174 default_attr() {
15175         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
15176 }
15177
15178 # usage: check_default_stripe_attr
15179 check_default_stripe_attr() {
15180         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
15181         case $1 in
15182         --stripe-count|-c)
15183                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
15184         --stripe-size|-S)
15185                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
15186         --stripe-index|-i)
15187                 EXPECTED=-1;;
15188         *)
15189                 error "unknown getstripe attr '$1'"
15190         esac
15191
15192         [ $ACTUAL == $EXPECTED ] ||
15193                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
15194 }
15195
15196 test_204a() {
15197         test_mkdir $DIR/$tdir
15198         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
15199
15200         check_default_stripe_attr --stripe-count
15201         check_default_stripe_attr --stripe-size
15202         check_default_stripe_attr --stripe-index
15203 }
15204 run_test 204a "Print default stripe attributes"
15205
15206 test_204b() {
15207         test_mkdir $DIR/$tdir
15208         $LFS setstripe --stripe-count 1 $DIR/$tdir
15209
15210         check_default_stripe_attr --stripe-size
15211         check_default_stripe_attr --stripe-index
15212 }
15213 run_test 204b "Print default stripe size and offset"
15214
15215 test_204c() {
15216         test_mkdir $DIR/$tdir
15217         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15218
15219         check_default_stripe_attr --stripe-count
15220         check_default_stripe_attr --stripe-index
15221 }
15222 run_test 204c "Print default stripe count and offset"
15223
15224 test_204d() {
15225         test_mkdir $DIR/$tdir
15226         $LFS setstripe --stripe-index 0 $DIR/$tdir
15227
15228         check_default_stripe_attr --stripe-count
15229         check_default_stripe_attr --stripe-size
15230 }
15231 run_test 204d "Print default stripe count and size"
15232
15233 test_204e() {
15234         test_mkdir $DIR/$tdir
15235         $LFS setstripe -d $DIR/$tdir
15236
15237         check_default_stripe_attr --stripe-count --raw
15238         check_default_stripe_attr --stripe-size --raw
15239         check_default_stripe_attr --stripe-index --raw
15240 }
15241 run_test 204e "Print raw stripe attributes"
15242
15243 test_204f() {
15244         test_mkdir $DIR/$tdir
15245         $LFS setstripe --stripe-count 1 $DIR/$tdir
15246
15247         check_default_stripe_attr --stripe-size --raw
15248         check_default_stripe_attr --stripe-index --raw
15249 }
15250 run_test 204f "Print raw stripe size and offset"
15251
15252 test_204g() {
15253         test_mkdir $DIR/$tdir
15254         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15255
15256         check_default_stripe_attr --stripe-count --raw
15257         check_default_stripe_attr --stripe-index --raw
15258 }
15259 run_test 204g "Print raw stripe count and offset"
15260
15261 test_204h() {
15262         test_mkdir $DIR/$tdir
15263         $LFS setstripe --stripe-index 0 $DIR/$tdir
15264
15265         check_default_stripe_attr --stripe-count --raw
15266         check_default_stripe_attr --stripe-size --raw
15267 }
15268 run_test 204h "Print raw stripe count and size"
15269
15270 # Figure out which job scheduler is being used, if any,
15271 # or use a fake one
15272 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
15273         JOBENV=SLURM_JOB_ID
15274 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
15275         JOBENV=LSB_JOBID
15276 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
15277         JOBENV=PBS_JOBID
15278 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
15279         JOBENV=LOADL_STEP_ID
15280 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
15281         JOBENV=JOB_ID
15282 else
15283         $LCTL list_param jobid_name > /dev/null 2>&1
15284         if [ $? -eq 0 ]; then
15285                 JOBENV=nodelocal
15286         else
15287                 JOBENV=FAKE_JOBID
15288         fi
15289 fi
15290 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
15291
15292 verify_jobstats() {
15293         local cmd=($1)
15294         shift
15295         local facets="$@"
15296
15297 # we don't really need to clear the stats for this test to work, since each
15298 # command has a unique jobid, but it makes debugging easier if needed.
15299 #       for facet in $facets; do
15300 #               local dev=$(convert_facet2label $facet)
15301 #               # clear old jobstats
15302 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
15303 #       done
15304
15305         # use a new JobID for each test, or we might see an old one
15306         [ "$JOBENV" = "FAKE_JOBID" ] &&
15307                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
15308
15309         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
15310
15311         [ "$JOBENV" = "nodelocal" ] && {
15312                 FAKE_JOBID=id.$testnum.%e.$RANDOM
15313                 $LCTL set_param jobid_name=$FAKE_JOBID
15314                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
15315         }
15316
15317         log "Test: ${cmd[*]}"
15318         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
15319
15320         if [ $JOBENV = "FAKE_JOBID" ]; then
15321                 FAKE_JOBID=$JOBVAL ${cmd[*]}
15322         else
15323                 ${cmd[*]}
15324         fi
15325
15326         # all files are created on OST0000
15327         for facet in $facets; do
15328                 local stats="*.$(convert_facet2label $facet).job_stats"
15329
15330                 # strip out libtool wrappers for in-tree executables
15331                 if [ $(do_facet $facet lctl get_param $stats |
15332                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
15333                         do_facet $facet lctl get_param $stats
15334                         error "No jobstats for $JOBVAL found on $facet::$stats"
15335                 fi
15336         done
15337 }
15338
15339 jobstats_set() {
15340         local new_jobenv=$1
15341
15342         set_persistent_param_and_check client "jobid_var" \
15343                 "$FSNAME.sys.jobid_var" $new_jobenv
15344 }
15345
15346 test_205() { # Job stats
15347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15348         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
15349                 skip "Need MDS version with at least 2.7.1"
15350         remote_mgs_nodsh && skip "remote MGS with nodsh"
15351         remote_mds_nodsh && skip "remote MDS with nodsh"
15352         remote_ost_nodsh && skip "remote OST with nodsh"
15353         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
15354                 skip "Server doesn't support jobstats"
15355         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
15356
15357         local old_jobenv=$($LCTL get_param -n jobid_var)
15358         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
15359
15360         if [[ $PERM_CMD == *"set_param -P"* ]]; then
15361                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
15362         else
15363                 stack_trap "do_facet mgs $PERM_CMD \
15364                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
15365         fi
15366         changelog_register
15367
15368         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
15369                                 mdt.*.job_cleanup_interval | head -n 1)
15370         local new_interval=5
15371         do_facet $SINGLEMDS \
15372                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
15373         stack_trap "do_facet $SINGLEMDS \
15374                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
15375         local start=$SECONDS
15376
15377         local cmd
15378         # mkdir
15379         cmd="mkdir $DIR/$tdir"
15380         verify_jobstats "$cmd" "$SINGLEMDS"
15381         # rmdir
15382         cmd="rmdir $DIR/$tdir"
15383         verify_jobstats "$cmd" "$SINGLEMDS"
15384         # mkdir on secondary MDT
15385         if [ $MDSCOUNT -gt 1 ]; then
15386                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
15387                 verify_jobstats "$cmd" "mds2"
15388         fi
15389         # mknod
15390         cmd="mknod $DIR/$tfile c 1 3"
15391         verify_jobstats "$cmd" "$SINGLEMDS"
15392         # unlink
15393         cmd="rm -f $DIR/$tfile"
15394         verify_jobstats "$cmd" "$SINGLEMDS"
15395         # create all files on OST0000 so verify_jobstats can find OST stats
15396         # open & close
15397         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
15398         verify_jobstats "$cmd" "$SINGLEMDS"
15399         # setattr
15400         cmd="touch $DIR/$tfile"
15401         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15402         # write
15403         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
15404         verify_jobstats "$cmd" "ost1"
15405         # read
15406         cancel_lru_locks osc
15407         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
15408         verify_jobstats "$cmd" "ost1"
15409         # truncate
15410         cmd="$TRUNCATE $DIR/$tfile 0"
15411         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15412         # rename
15413         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
15414         verify_jobstats "$cmd" "$SINGLEMDS"
15415         # jobstats expiry - sleep until old stats should be expired
15416         local left=$((new_interval + 5 - (SECONDS - start)))
15417         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
15418                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
15419                         "0" $left
15420         cmd="mkdir $DIR/$tdir.expire"
15421         verify_jobstats "$cmd" "$SINGLEMDS"
15422         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
15423             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
15424
15425         # Ensure that jobid are present in changelog (if supported by MDS)
15426         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
15427                 changelog_dump | tail -10
15428                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
15429                 [ $jobids -eq 9 ] ||
15430                         error "Wrong changelog jobid count $jobids != 9"
15431
15432                 # LU-5862
15433                 JOBENV="disable"
15434                 jobstats_set $JOBENV
15435                 touch $DIR/$tfile
15436                 changelog_dump | grep $tfile
15437                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
15438                 [ $jobids -eq 0 ] ||
15439                         error "Unexpected jobids when jobid_var=$JOBENV"
15440         fi
15441
15442         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
15443         JOBENV="JOBCOMPLEX"
15444         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
15445
15446         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
15447 }
15448 run_test 205 "Verify job stats"
15449
15450 # LU-1480, LU-1773 and LU-1657
15451 test_206() {
15452         mkdir -p $DIR/$tdir
15453         $LFS setstripe -c -1 $DIR/$tdir
15454 #define OBD_FAIL_LOV_INIT 0x1403
15455         $LCTL set_param fail_loc=0xa0001403
15456         $LCTL set_param fail_val=1
15457         touch $DIR/$tdir/$tfile || true
15458 }
15459 run_test 206 "fail lov_init_raid0() doesn't lbug"
15460
15461 test_207a() {
15462         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15463         local fsz=`stat -c %s $DIR/$tfile`
15464         cancel_lru_locks mdc
15465
15466         # do not return layout in getattr intent
15467 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
15468         $LCTL set_param fail_loc=0x170
15469         local sz=`stat -c %s $DIR/$tfile`
15470
15471         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
15472
15473         rm -rf $DIR/$tfile
15474 }
15475 run_test 207a "can refresh layout at glimpse"
15476
15477 test_207b() {
15478         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15479         local cksum=`md5sum $DIR/$tfile`
15480         local fsz=`stat -c %s $DIR/$tfile`
15481         cancel_lru_locks mdc
15482         cancel_lru_locks osc
15483
15484         # do not return layout in getattr intent
15485 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
15486         $LCTL set_param fail_loc=0x171
15487
15488         # it will refresh layout after the file is opened but before read issues
15489         echo checksum is "$cksum"
15490         echo "$cksum" |md5sum -c --quiet || error "file differs"
15491
15492         rm -rf $DIR/$tfile
15493 }
15494 run_test 207b "can refresh layout at open"
15495
15496 test_208() {
15497         # FIXME: in this test suite, only RD lease is used. This is okay
15498         # for now as only exclusive open is supported. After generic lease
15499         # is done, this test suite should be revised. - Jinshan
15500
15501         remote_mds_nodsh && skip "remote MDS with nodsh"
15502         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
15503                 skip "Need MDS version at least 2.4.52"
15504
15505         echo "==== test 1: verify get lease work"
15506         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
15507
15508         echo "==== test 2: verify lease can be broken by upcoming open"
15509         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15510         local PID=$!
15511         sleep 1
15512
15513         $MULTIOP $DIR/$tfile oO_RDONLY:c
15514         kill -USR1 $PID && wait $PID || error "break lease error"
15515
15516         echo "==== test 3: verify lease can't be granted if an open already exists"
15517         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
15518         local PID=$!
15519         sleep 1
15520
15521         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
15522         kill -USR1 $PID && wait $PID || error "open file error"
15523
15524         echo "==== test 4: lease can sustain over recovery"
15525         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
15526         PID=$!
15527         sleep 1
15528
15529         fail mds1
15530
15531         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
15532
15533         echo "==== test 5: lease broken can't be regained by replay"
15534         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15535         PID=$!
15536         sleep 1
15537
15538         # open file to break lease and then recovery
15539         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
15540         fail mds1
15541
15542         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
15543
15544         rm -f $DIR/$tfile
15545 }
15546 run_test 208 "Exclusive open"
15547
15548 test_209() {
15549         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15550                 skip_env "must have disp_stripe"
15551
15552         touch $DIR/$tfile
15553         sync; sleep 5; sync;
15554
15555         echo 3 > /proc/sys/vm/drop_caches
15556         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15557
15558         # open/close 500 times
15559         for i in $(seq 500); do
15560                 cat $DIR/$tfile
15561         done
15562
15563         echo 3 > /proc/sys/vm/drop_caches
15564         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15565
15566         echo "before: $req_before, after: $req_after"
15567         [ $((req_after - req_before)) -ge 300 ] &&
15568                 error "open/close requests are not freed"
15569         return 0
15570 }
15571 run_test 209 "read-only open/close requests should be freed promptly"
15572
15573 test_212() {
15574         size=`date +%s`
15575         size=$((size % 8192 + 1))
15576         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
15577         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
15578         rm -f $DIR/f212 $DIR/f212.xyz
15579 }
15580 run_test 212 "Sendfile test ============================================"
15581
15582 test_213() {
15583         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
15584         cancel_lru_locks osc
15585         lctl set_param fail_loc=0x8000040f
15586         # generate a read lock
15587         cat $DIR/$tfile > /dev/null
15588         # write to the file, it will try to cancel the above read lock.
15589         cat /etc/hosts >> $DIR/$tfile
15590 }
15591 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
15592
15593 test_214() { # for bug 20133
15594         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
15595         for (( i=0; i < 340; i++ )) ; do
15596                 touch $DIR/$tdir/d214c/a$i
15597         done
15598
15599         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
15600         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
15601         ls $DIR/d214c || error "ls $DIR/d214c failed"
15602         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
15603         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
15604 }
15605 run_test 214 "hash-indexed directory test - bug 20133"
15606
15607 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
15608 create_lnet_proc_files() {
15609         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
15610 }
15611
15612 # counterpart of create_lnet_proc_files
15613 remove_lnet_proc_files() {
15614         rm -f $TMP/lnet_$1.sys
15615 }
15616
15617 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15618 # 3rd arg as regexp for body
15619 check_lnet_proc_stats() {
15620         local l=$(cat "$TMP/lnet_$1" |wc -l)
15621         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
15622
15623         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
15624 }
15625
15626 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15627 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
15628 # optional and can be regexp for 2nd line (lnet.routes case)
15629 check_lnet_proc_entry() {
15630         local blp=2          # blp stands for 'position of 1st line of body'
15631         [ -z "$5" ] || blp=3 # lnet.routes case
15632
15633         local l=$(cat "$TMP/lnet_$1" |wc -l)
15634         # subtracting one from $blp because the body can be empty
15635         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
15636
15637         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
15638                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
15639
15640         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
15641                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
15642
15643         # bail out if any unexpected line happened
15644         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15645         [ "$?" != 0 ] || error "$2 misformatted"
15646 }
15647
15648 test_215() { # for bugs 18102, 21079, 21517
15649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15650
15651         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15652         local P='[1-9][0-9]*'           # positive numeric
15653         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15654         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15655         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15656         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15657
15658         local L1 # regexp for 1st line
15659         local L2 # regexp for 2nd line (optional)
15660         local BR # regexp for the rest (body)
15661
15662         # lnet.stats should look as 11 space-separated non-negative numerics
15663         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15664         create_lnet_proc_files "stats"
15665         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15666         remove_lnet_proc_files "stats"
15667
15668         # lnet.routes should look like this:
15669         # Routing disabled/enabled
15670         # net hops priority state router
15671         # where net is a string like tcp0, hops > 0, priority >= 0,
15672         # state is up/down,
15673         # router is a string like 192.168.1.1@tcp2
15674         L1="^Routing (disabled|enabled)$"
15675         L2="^net +hops +priority +state +router$"
15676         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15677         create_lnet_proc_files "routes"
15678         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15679         remove_lnet_proc_files "routes"
15680
15681         # lnet.routers should look like this:
15682         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15683         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15684         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15685         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15686         L1="^ref +rtr_ref +alive +router$"
15687         BR="^$P +$P +(up|down) +$NID$"
15688         create_lnet_proc_files "routers"
15689         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15690         remove_lnet_proc_files "routers"
15691
15692         # lnet.peers should look like this:
15693         # nid refs state last max rtr min tx min queue
15694         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15695         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15696         # numeric (0 or >0 or <0), queue >= 0.
15697         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15698         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15699         create_lnet_proc_files "peers"
15700         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15701         remove_lnet_proc_files "peers"
15702
15703         # lnet.buffers  should look like this:
15704         # pages count credits min
15705         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15706         L1="^pages +count +credits +min$"
15707         BR="^ +$N +$N +$I +$I$"
15708         create_lnet_proc_files "buffers"
15709         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15710         remove_lnet_proc_files "buffers"
15711
15712         # lnet.nis should look like this:
15713         # nid status alive refs peer rtr max tx min
15714         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15715         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15716         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15717         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15718         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15719         create_lnet_proc_files "nis"
15720         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15721         remove_lnet_proc_files "nis"
15722
15723         # can we successfully write to lnet.stats?
15724         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15725 }
15726 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15727
15728 test_216() { # bug 20317
15729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15730         remote_ost_nodsh && skip "remote OST with nodsh"
15731
15732         local node
15733         local facets=$(get_facets OST)
15734         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15735
15736         save_lustre_params client "osc.*.contention_seconds" > $p
15737         save_lustre_params $facets \
15738                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15739         save_lustre_params $facets \
15740                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15741         save_lustre_params $facets \
15742                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15743         clear_stats osc.*.osc_stats
15744
15745         # agressive lockless i/o settings
15746         do_nodes $(comma_list $(osts_nodes)) \
15747                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15748                         ldlm.namespaces.filter-*.contended_locks=0 \
15749                         ldlm.namespaces.filter-*.contention_seconds=60"
15750         lctl set_param -n osc.*.contention_seconds=60
15751
15752         $DIRECTIO write $DIR/$tfile 0 10 4096
15753         $CHECKSTAT -s 40960 $DIR/$tfile
15754
15755         # disable lockless i/o
15756         do_nodes $(comma_list $(osts_nodes)) \
15757                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15758                         ldlm.namespaces.filter-*.contended_locks=32 \
15759                         ldlm.namespaces.filter-*.contention_seconds=0"
15760         lctl set_param -n osc.*.contention_seconds=0
15761         clear_stats osc.*.osc_stats
15762
15763         dd if=/dev/zero of=$DIR/$tfile count=0
15764         $CHECKSTAT -s 0 $DIR/$tfile
15765
15766         restore_lustre_params <$p
15767         rm -f $p
15768         rm $DIR/$tfile
15769 }
15770 run_test 216 "check lockless direct write updates file size and kms correctly"
15771
15772 test_217() { # bug 22430
15773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15774
15775         local node
15776         local nid
15777
15778         for node in $(nodes_list); do
15779                 nid=$(host_nids_address $node $NETTYPE)
15780                 if [[ $nid = *-* ]] ; then
15781                         echo "lctl ping $(h2nettype $nid)"
15782                         lctl ping $(h2nettype $nid)
15783                 else
15784                         echo "skipping $node (no hyphen detected)"
15785                 fi
15786         done
15787 }
15788 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15789
15790 test_218() {
15791        # do directio so as not to populate the page cache
15792        log "creating a 10 Mb file"
15793        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15794        log "starting reads"
15795        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15796        log "truncating the file"
15797        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15798        log "killing dd"
15799        kill %+ || true # reads might have finished
15800        echo "wait until dd is finished"
15801        wait
15802        log "removing the temporary file"
15803        rm -rf $DIR/$tfile || error "tmp file removal failed"
15804 }
15805 run_test 218 "parallel read and truncate should not deadlock"
15806
15807 test_219() {
15808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15809
15810         # write one partial page
15811         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15812         # set no grant so vvp_io_commit_write will do sync write
15813         $LCTL set_param fail_loc=0x411
15814         # write a full page at the end of file
15815         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15816
15817         $LCTL set_param fail_loc=0
15818         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15819         $LCTL set_param fail_loc=0x411
15820         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15821
15822         # LU-4201
15823         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15824         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15825 }
15826 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15827
15828 test_220() { #LU-325
15829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15830         remote_ost_nodsh && skip "remote OST with nodsh"
15831         remote_mds_nodsh && skip "remote MDS with nodsh"
15832         remote_mgs_nodsh && skip "remote MGS with nodsh"
15833
15834         local OSTIDX=0
15835
15836         # create on MDT0000 so the last_id and next_id are correct
15837         mkdir $DIR/$tdir
15838         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15839         OST=${OST%_UUID}
15840
15841         # on the mdt's osc
15842         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15843         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15844                         osp.$mdtosc_proc1.prealloc_last_id)
15845         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15846                         osp.$mdtosc_proc1.prealloc_next_id)
15847
15848         $LFS df -i
15849
15850         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15851         #define OBD_FAIL_OST_ENOINO              0x229
15852         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15853         create_pool $FSNAME.$TESTNAME || return 1
15854         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15855
15856         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15857
15858         MDSOBJS=$((last_id - next_id))
15859         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15860
15861         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15862         echo "OST still has $count kbytes free"
15863
15864         echo "create $MDSOBJS files @next_id..."
15865         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15866
15867         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15868                         osp.$mdtosc_proc1.prealloc_last_id)
15869         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15870                         osp.$mdtosc_proc1.prealloc_next_id)
15871
15872         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15873         $LFS df -i
15874
15875         echo "cleanup..."
15876
15877         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15878         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15879
15880         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15881                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15882         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15883                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15884         echo "unlink $MDSOBJS files @$next_id..."
15885         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15886 }
15887 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15888
15889 test_221() {
15890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15891
15892         dd if=`which date` of=$MOUNT/date oflag=sync
15893         chmod +x $MOUNT/date
15894
15895         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15896         $LCTL set_param fail_loc=0x80001401
15897
15898         $MOUNT/date > /dev/null
15899         rm -f $MOUNT/date
15900 }
15901 run_test 221 "make sure fault and truncate race to not cause OOM"
15902
15903 test_222a () {
15904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15905
15906         rm -rf $DIR/$tdir
15907         test_mkdir $DIR/$tdir
15908         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15909         createmany -o $DIR/$tdir/$tfile 10
15910         cancel_lru_locks mdc
15911         cancel_lru_locks osc
15912         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15913         $LCTL set_param fail_loc=0x31a
15914         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15915         $LCTL set_param fail_loc=0
15916         rm -r $DIR/$tdir
15917 }
15918 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15919
15920 test_222b () {
15921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15922
15923         rm -rf $DIR/$tdir
15924         test_mkdir $DIR/$tdir
15925         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15926         createmany -o $DIR/$tdir/$tfile 10
15927         cancel_lru_locks mdc
15928         cancel_lru_locks osc
15929         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15930         $LCTL set_param fail_loc=0x31a
15931         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15932         $LCTL set_param fail_loc=0
15933 }
15934 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15935
15936 test_223 () {
15937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15938
15939         rm -rf $DIR/$tdir
15940         test_mkdir $DIR/$tdir
15941         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15942         createmany -o $DIR/$tdir/$tfile 10
15943         cancel_lru_locks mdc
15944         cancel_lru_locks osc
15945         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15946         $LCTL set_param fail_loc=0x31b
15947         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15948         $LCTL set_param fail_loc=0
15949         rm -r $DIR/$tdir
15950 }
15951 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15952
15953 test_224a() { # LU-1039, MRP-303
15954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15955
15956         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15957         $LCTL set_param fail_loc=0x508
15958         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15959         $LCTL set_param fail_loc=0
15960         df $DIR
15961 }
15962 run_test 224a "Don't panic on bulk IO failure"
15963
15964 test_224b() { # LU-1039, MRP-303
15965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15966
15967         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
15968         cancel_lru_locks osc
15969         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
15970         $LCTL set_param fail_loc=0x515
15971         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
15972         $LCTL set_param fail_loc=0
15973         df $DIR
15974 }
15975 run_test 224b "Don't panic on bulk IO failure"
15976
15977 test_224c() { # LU-6441
15978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15979         remote_mds_nodsh && skip "remote MDS with nodsh"
15980
15981         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15982         save_writethrough $p
15983         set_cache writethrough on
15984
15985         local pages_per_rpc=$($LCTL get_param \
15986                                 osc.*.max_pages_per_rpc)
15987         local at_max=$($LCTL get_param -n at_max)
15988         local timeout=$($LCTL get_param -n timeout)
15989         local test_at="at_max"
15990         local param_at="$FSNAME.sys.at_max"
15991         local test_timeout="timeout"
15992         local param_timeout="$FSNAME.sys.timeout"
15993
15994         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
15995
15996         set_persistent_param_and_check client "$test_at" "$param_at" 0
15997         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
15998
15999         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
16000         do_facet ost1 "$LCTL set_param fail_loc=0x520"
16001         $LFS setstripe -c 1 -i 0 $DIR/$tfile
16002         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
16003         sync
16004         do_facet ost1 "$LCTL set_param fail_loc=0"
16005
16006         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
16007         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
16008                 $timeout
16009
16010         $LCTL set_param -n $pages_per_rpc
16011         restore_lustre_params < $p
16012         rm -f $p
16013 }
16014 run_test 224c "Don't hang if one of md lost during large bulk RPC"
16015
16016 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
16017 test_225a () {
16018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16019         if [ -z ${MDSSURVEY} ]; then
16020                 skip_env "mds-survey not found"
16021         fi
16022         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16023                 skip "Need MDS version at least 2.2.51"
16024
16025         local mds=$(facet_host $SINGLEMDS)
16026         local target=$(do_nodes $mds 'lctl dl' |
16027                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16028
16029         local cmd1="file_count=1000 thrhi=4"
16030         local cmd2="dir_count=2 layer=mdd stripe_count=0"
16031         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16032         local cmd="$cmd1 $cmd2 $cmd3"
16033
16034         rm -f ${TMP}/mds_survey*
16035         echo + $cmd
16036         eval $cmd || error "mds-survey with zero-stripe failed"
16037         cat ${TMP}/mds_survey*
16038         rm -f ${TMP}/mds_survey*
16039 }
16040 run_test 225a "Metadata survey sanity with zero-stripe"
16041
16042 test_225b () {
16043         if [ -z ${MDSSURVEY} ]; then
16044                 skip_env "mds-survey not found"
16045         fi
16046         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16047                 skip "Need MDS version at least 2.2.51"
16048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16049         remote_mds_nodsh && skip "remote MDS with nodsh"
16050         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
16051                 skip_env "Need to mount OST to test"
16052         fi
16053
16054         local mds=$(facet_host $SINGLEMDS)
16055         local target=$(do_nodes $mds 'lctl dl' |
16056                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16057
16058         local cmd1="file_count=1000 thrhi=4"
16059         local cmd2="dir_count=2 layer=mdd stripe_count=1"
16060         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16061         local cmd="$cmd1 $cmd2 $cmd3"
16062
16063         rm -f ${TMP}/mds_survey*
16064         echo + $cmd
16065         eval $cmd || error "mds-survey with stripe_count failed"
16066         cat ${TMP}/mds_survey*
16067         rm -f ${TMP}/mds_survey*
16068 }
16069 run_test 225b "Metadata survey sanity with stripe_count = 1"
16070
16071 mcreate_path2fid () {
16072         local mode=$1
16073         local major=$2
16074         local minor=$3
16075         local name=$4
16076         local desc=$5
16077         local path=$DIR/$tdir/$name
16078         local fid
16079         local rc
16080         local fid_path
16081
16082         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
16083                 error "cannot create $desc"
16084
16085         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
16086         rc=$?
16087         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
16088
16089         fid_path=$($LFS fid2path $MOUNT $fid)
16090         rc=$?
16091         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
16092
16093         [ "$path" == "$fid_path" ] ||
16094                 error "fid2path returned $fid_path, expected $path"
16095
16096         echo "pass with $path and $fid"
16097 }
16098
16099 test_226a () {
16100         rm -rf $DIR/$tdir
16101         mkdir -p $DIR/$tdir
16102
16103         mcreate_path2fid 0010666 0 0 fifo "FIFO"
16104         mcreate_path2fid 0020666 1 3 null "character special file (null)"
16105         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
16106         mcreate_path2fid 0040666 0 0 dir "directory"
16107         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
16108         mcreate_path2fid 0100666 0 0 file "regular file"
16109         mcreate_path2fid 0120666 0 0 link "symbolic link"
16110         mcreate_path2fid 0140666 0 0 sock "socket"
16111 }
16112 run_test 226a "call path2fid and fid2path on files of all type"
16113
16114 test_226b () {
16115         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16116
16117         local MDTIDX=1
16118
16119         rm -rf $DIR/$tdir
16120         mkdir -p $DIR/$tdir
16121         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
16122                 error "create remote directory failed"
16123         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
16124         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
16125                                 "character special file (null)"
16126         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
16127                                 "character special file (no device)"
16128         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
16129         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
16130                                 "block special file (loop)"
16131         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
16132         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
16133         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
16134 }
16135 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
16136
16137 # LU-1299 Executing or running ldd on a truncated executable does not
16138 # cause an out-of-memory condition.
16139 test_227() {
16140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16141         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
16142
16143         dd if=$(which date) of=$MOUNT/date bs=1k count=1
16144         chmod +x $MOUNT/date
16145
16146         $MOUNT/date > /dev/null
16147         ldd $MOUNT/date > /dev/null
16148         rm -f $MOUNT/date
16149 }
16150 run_test 227 "running truncated executable does not cause OOM"
16151
16152 # LU-1512 try to reuse idle OI blocks
16153 test_228a() {
16154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16155         remote_mds_nodsh && skip "remote MDS with nodsh"
16156         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16157
16158         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16159         local myDIR=$DIR/$tdir
16160
16161         mkdir -p $myDIR
16162         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16163         $LCTL set_param fail_loc=0x80001002
16164         createmany -o $myDIR/t- 10000
16165         $LCTL set_param fail_loc=0
16166         # The guard is current the largest FID holder
16167         touch $myDIR/guard
16168         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16169                     tr -d '[')
16170         local IDX=$(($SEQ % 64))
16171
16172         do_facet $SINGLEMDS sync
16173         # Make sure journal flushed.
16174         sleep 6
16175         local blk1=$(do_facet $SINGLEMDS \
16176                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16177                      grep Blockcount | awk '{print $4}')
16178
16179         # Remove old files, some OI blocks will become idle.
16180         unlinkmany $myDIR/t- 10000
16181         # Create new files, idle OI blocks should be reused.
16182         createmany -o $myDIR/t- 2000
16183         do_facet $SINGLEMDS sync
16184         # Make sure journal flushed.
16185         sleep 6
16186         local blk2=$(do_facet $SINGLEMDS \
16187                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16188                      grep Blockcount | awk '{print $4}')
16189
16190         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16191 }
16192 run_test 228a "try to reuse idle OI blocks"
16193
16194 test_228b() {
16195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16196         remote_mds_nodsh && skip "remote MDS with nodsh"
16197         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16198
16199         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16200         local myDIR=$DIR/$tdir
16201
16202         mkdir -p $myDIR
16203         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16204         $LCTL set_param fail_loc=0x80001002
16205         createmany -o $myDIR/t- 10000
16206         $LCTL set_param fail_loc=0
16207         # The guard is current the largest FID holder
16208         touch $myDIR/guard
16209         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16210                     tr -d '[')
16211         local IDX=$(($SEQ % 64))
16212
16213         do_facet $SINGLEMDS sync
16214         # Make sure journal flushed.
16215         sleep 6
16216         local blk1=$(do_facet $SINGLEMDS \
16217                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16218                      grep Blockcount | awk '{print $4}')
16219
16220         # Remove old files, some OI blocks will become idle.
16221         unlinkmany $myDIR/t- 10000
16222
16223         # stop the MDT
16224         stop $SINGLEMDS || error "Fail to stop MDT."
16225         # remount the MDT
16226         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
16227
16228         df $MOUNT || error "Fail to df."
16229         # Create new files, idle OI blocks should be reused.
16230         createmany -o $myDIR/t- 2000
16231         do_facet $SINGLEMDS sync
16232         # Make sure journal flushed.
16233         sleep 6
16234         local blk2=$(do_facet $SINGLEMDS \
16235                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16236                      grep Blockcount | awk '{print $4}')
16237
16238         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16239 }
16240 run_test 228b "idle OI blocks can be reused after MDT restart"
16241
16242 #LU-1881
16243 test_228c() {
16244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16245         remote_mds_nodsh && skip "remote MDS with nodsh"
16246         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16247
16248         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16249         local myDIR=$DIR/$tdir
16250
16251         mkdir -p $myDIR
16252         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16253         $LCTL set_param fail_loc=0x80001002
16254         # 20000 files can guarantee there are index nodes in the OI file
16255         createmany -o $myDIR/t- 20000
16256         $LCTL set_param fail_loc=0
16257         # The guard is current the largest FID holder
16258         touch $myDIR/guard
16259         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16260                     tr -d '[')
16261         local IDX=$(($SEQ % 64))
16262
16263         do_facet $SINGLEMDS sync
16264         # Make sure journal flushed.
16265         sleep 6
16266         local blk1=$(do_facet $SINGLEMDS \
16267                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16268                      grep Blockcount | awk '{print $4}')
16269
16270         # Remove old files, some OI blocks will become idle.
16271         unlinkmany $myDIR/t- 20000
16272         rm -f $myDIR/guard
16273         # The OI file should become empty now
16274
16275         # Create new files, idle OI blocks should be reused.
16276         createmany -o $myDIR/t- 2000
16277         do_facet $SINGLEMDS sync
16278         # Make sure journal flushed.
16279         sleep 6
16280         local blk2=$(do_facet $SINGLEMDS \
16281                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16282                      grep Blockcount | awk '{print $4}')
16283
16284         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16285 }
16286 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
16287
16288 test_229() { # LU-2482, LU-3448
16289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16290         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
16291         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
16292                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
16293
16294         rm -f $DIR/$tfile
16295
16296         # Create a file with a released layout and stripe count 2.
16297         $MULTIOP $DIR/$tfile H2c ||
16298                 error "failed to create file with released layout"
16299
16300         $LFS getstripe -v $DIR/$tfile
16301
16302         local pattern=$($LFS getstripe -L $DIR/$tfile)
16303         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
16304
16305         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
16306                 error "getstripe"
16307         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
16308         stat $DIR/$tfile || error "failed to stat released file"
16309
16310         chown $RUNAS_ID $DIR/$tfile ||
16311                 error "chown $RUNAS_ID $DIR/$tfile failed"
16312
16313         chgrp $RUNAS_ID $DIR/$tfile ||
16314                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
16315
16316         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
16317         rm $DIR/$tfile || error "failed to remove released file"
16318 }
16319 run_test 229 "getstripe/stat/rm/attr changes work on released files"
16320
16321 test_230a() {
16322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16323         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16324         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16325                 skip "Need MDS version at least 2.11.52"
16326
16327         local MDTIDX=1
16328
16329         test_mkdir $DIR/$tdir
16330         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
16331         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
16332         [ $mdt_idx -ne 0 ] &&
16333                 error "create local directory on wrong MDT $mdt_idx"
16334
16335         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
16336                         error "create remote directory failed"
16337         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
16338         [ $mdt_idx -ne $MDTIDX ] &&
16339                 error "create remote directory on wrong MDT $mdt_idx"
16340
16341         createmany -o $DIR/$tdir/test_230/t- 10 ||
16342                 error "create files on remote directory failed"
16343         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
16344         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
16345         rm -r $DIR/$tdir || error "unlink remote directory failed"
16346 }
16347 run_test 230a "Create remote directory and files under the remote directory"
16348
16349 test_230b() {
16350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16351         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16352         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16353                 skip "Need MDS version at least 2.11.52"
16354
16355         local MDTIDX=1
16356         local mdt_index
16357         local i
16358         local file
16359         local pid
16360         local stripe_count
16361         local migrate_dir=$DIR/$tdir/migrate_dir
16362         local other_dir=$DIR/$tdir/other_dir
16363
16364         test_mkdir $DIR/$tdir
16365         test_mkdir -i0 -c1 $migrate_dir
16366         test_mkdir -i0 -c1 $other_dir
16367         for ((i=0; i<10; i++)); do
16368                 mkdir -p $migrate_dir/dir_${i}
16369                 createmany -o $migrate_dir/dir_${i}/f 10 ||
16370                         error "create files under remote dir failed $i"
16371         done
16372
16373         cp /etc/passwd $migrate_dir/$tfile
16374         cp /etc/passwd $other_dir/$tfile
16375         chattr +SAD $migrate_dir
16376         chattr +SAD $migrate_dir/$tfile
16377
16378         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16379         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16380         local old_dir_mode=$(stat -c%f $migrate_dir)
16381         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
16382
16383         mkdir -p $migrate_dir/dir_default_stripe2
16384         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
16385         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
16386
16387         mkdir -p $other_dir
16388         ln $migrate_dir/$tfile $other_dir/luna
16389         ln $migrate_dir/$tfile $migrate_dir/sofia
16390         ln $other_dir/$tfile $migrate_dir/david
16391         ln -s $migrate_dir/$tfile $other_dir/zachary
16392         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
16393         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
16394
16395         $LFS migrate -m $MDTIDX $migrate_dir ||
16396                 error "fails on migrating remote dir to MDT1"
16397
16398         echo "migratate to MDT1, then checking.."
16399         for ((i = 0; i < 10; i++)); do
16400                 for file in $(find $migrate_dir/dir_${i}); do
16401                         mdt_index=$($LFS getstripe -m $file)
16402                         [ $mdt_index == $MDTIDX ] ||
16403                                 error "$file is not on MDT${MDTIDX}"
16404                 done
16405         done
16406
16407         # the multiple link file should still in MDT0
16408         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
16409         [ $mdt_index == 0 ] ||
16410                 error "$file is not on MDT${MDTIDX}"
16411
16412         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16413         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16414                 error " expect $old_dir_flag get $new_dir_flag"
16415
16416         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16417         [ "$old_file_flag" = "$new_file_flag" ] ||
16418                 error " expect $old_file_flag get $new_file_flag"
16419
16420         local new_dir_mode=$(stat -c%f $migrate_dir)
16421         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16422                 error "expect mode $old_dir_mode get $new_dir_mode"
16423
16424         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16425         [ "$old_file_mode" = "$new_file_mode" ] ||
16426                 error "expect mode $old_file_mode get $new_file_mode"
16427
16428         diff /etc/passwd $migrate_dir/$tfile ||
16429                 error "$tfile different after migration"
16430
16431         diff /etc/passwd $other_dir/luna ||
16432                 error "luna different after migration"
16433
16434         diff /etc/passwd $migrate_dir/sofia ||
16435                 error "sofia different after migration"
16436
16437         diff /etc/passwd $migrate_dir/david ||
16438                 error "david different after migration"
16439
16440         diff /etc/passwd $other_dir/zachary ||
16441                 error "zachary different after migration"
16442
16443         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16444                 error "${tfile}_ln different after migration"
16445
16446         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16447                 error "${tfile}_ln_other different after migration"
16448
16449         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
16450         [ $stripe_count = 2 ] ||
16451                 error "dir strpe_count $d != 2 after migration."
16452
16453         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
16454         [ $stripe_count = 2 ] ||
16455                 error "file strpe_count $d != 2 after migration."
16456
16457         #migrate back to MDT0
16458         MDTIDX=0
16459
16460         $LFS migrate -m $MDTIDX $migrate_dir ||
16461                 error "fails on migrating remote dir to MDT0"
16462
16463         echo "migrate back to MDT0, checking.."
16464         for file in $(find $migrate_dir); do
16465                 mdt_index=$($LFS getstripe -m $file)
16466                 [ $mdt_index == $MDTIDX ] ||
16467                         error "$file is not on MDT${MDTIDX}"
16468         done
16469
16470         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16471         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16472                 error " expect $old_dir_flag get $new_dir_flag"
16473
16474         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16475         [ "$old_file_flag" = "$new_file_flag" ] ||
16476                 error " expect $old_file_flag get $new_file_flag"
16477
16478         local new_dir_mode=$(stat -c%f $migrate_dir)
16479         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16480                 error "expect mode $old_dir_mode get $new_dir_mode"
16481
16482         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16483         [ "$old_file_mode" = "$new_file_mode" ] ||
16484                 error "expect mode $old_file_mode get $new_file_mode"
16485
16486         diff /etc/passwd ${migrate_dir}/$tfile ||
16487                 error "$tfile different after migration"
16488
16489         diff /etc/passwd ${other_dir}/luna ||
16490                 error "luna different after migration"
16491
16492         diff /etc/passwd ${migrate_dir}/sofia ||
16493                 error "sofia different after migration"
16494
16495         diff /etc/passwd ${other_dir}/zachary ||
16496                 error "zachary different after migration"
16497
16498         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16499                 error "${tfile}_ln different after migration"
16500
16501         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16502                 error "${tfile}_ln_other different after migration"
16503
16504         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
16505         [ $stripe_count = 2 ] ||
16506                 error "dir strpe_count $d != 2 after migration."
16507
16508         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
16509         [ $stripe_count = 2 ] ||
16510                 error "file strpe_count $d != 2 after migration."
16511
16512         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16513 }
16514 run_test 230b "migrate directory"
16515
16516 test_230c() {
16517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16518         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16519         remote_mds_nodsh && skip "remote MDS with nodsh"
16520         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16521                 skip "Need MDS version at least 2.11.52"
16522
16523         local MDTIDX=1
16524         local total=3
16525         local mdt_index
16526         local file
16527         local migrate_dir=$DIR/$tdir/migrate_dir
16528
16529         #If migrating directory fails in the middle, all entries of
16530         #the directory is still accessiable.
16531         test_mkdir $DIR/$tdir
16532         test_mkdir -i0 -c1 $migrate_dir
16533         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
16534         stat $migrate_dir
16535         createmany -o $migrate_dir/f $total ||
16536                 error "create files under ${migrate_dir} failed"
16537
16538         # fail after migrating top dir, and this will fail only once, so the
16539         # first sub file migration will fail (currently f3), others succeed.
16540         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16541         do_facet mds1 lctl set_param fail_loc=0x1801
16542         local t=$(ls $migrate_dir | wc -l)
16543         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
16544                 error "migrate should fail"
16545         local u=$(ls $migrate_dir | wc -l)
16546         [ "$u" == "$t" ] || error "$u != $t during migration"
16547
16548         # add new dir/file should succeed
16549         mkdir $migrate_dir/dir ||
16550                 error "mkdir failed under migrating directory"
16551         touch $migrate_dir/file ||
16552                 error "create file failed under migrating directory"
16553
16554         # add file with existing name should fail
16555         for file in $migrate_dir/f*; do
16556                 stat $file > /dev/null || error "stat $file failed"
16557                 $OPENFILE -f O_CREAT:O_EXCL $file &&
16558                         error "open(O_CREAT|O_EXCL) $file should fail"
16559                 $MULTIOP $file m && error "create $file should fail"
16560                 touch $DIR/$tdir/remote_dir/$tfile ||
16561                         error "touch $tfile failed"
16562                 ln $DIR/$tdir/remote_dir/$tfile $file &&
16563                         error "link $file should fail"
16564                 mdt_index=$($LFS getstripe -m $file)
16565                 if [ $mdt_index == 0 ]; then
16566                         # file failed to migrate is not allowed to rename to
16567                         mv $DIR/$tdir/remote_dir/$tfile $file &&
16568                                 error "rename to $file should fail"
16569                 else
16570                         mv $DIR/$tdir/remote_dir/$tfile $file ||
16571                                 error "rename to $file failed"
16572                 fi
16573                 echo hello >> $file || error "write $file failed"
16574         done
16575
16576         # resume migration with different options should fail
16577         $LFS migrate -m 0 $migrate_dir &&
16578                 error "migrate -m 0 $migrate_dir should fail"
16579
16580         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
16581                 error "migrate -c 2 $migrate_dir should fail"
16582
16583         # resume migration should succeed
16584         $LFS migrate -m $MDTIDX $migrate_dir ||
16585                 error "migrate $migrate_dir failed"
16586
16587         echo "Finish migration, then checking.."
16588         for file in $(find $migrate_dir); do
16589                 mdt_index=$($LFS getstripe -m $file)
16590                 [ $mdt_index == $MDTIDX ] ||
16591                         error "$file is not on MDT${MDTIDX}"
16592         done
16593
16594         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16595 }
16596 run_test 230c "check directory accessiblity if migration failed"
16597
16598 test_230d() {
16599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16600         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16601         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16602                 skip "Need MDS version at least 2.11.52"
16603         # LU-11235
16604         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
16605
16606         local migrate_dir=$DIR/$tdir/migrate_dir
16607         local old_index
16608         local new_index
16609         local old_count
16610         local new_count
16611         local new_hash
16612         local mdt_index
16613         local i
16614         local j
16615
16616         old_index=$((RANDOM % MDSCOUNT))
16617         old_count=$((MDSCOUNT - old_index))
16618         new_index=$((RANDOM % MDSCOUNT))
16619         new_count=$((MDSCOUNT - new_index))
16620         new_hash="all_char"
16621
16622         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
16623         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
16624
16625         test_mkdir $DIR/$tdir
16626         test_mkdir -i $old_index -c $old_count $migrate_dir
16627
16628         for ((i=0; i<100; i++)); do
16629                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
16630                 createmany -o $migrate_dir/dir_${i}/f 100 ||
16631                         error "create files under remote dir failed $i"
16632         done
16633
16634         echo -n "Migrate from MDT$old_index "
16635         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
16636         echo -n "to MDT$new_index"
16637         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16638         echo
16639
16640         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16641         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16642                 error "migrate remote dir error"
16643
16644         echo "Finish migration, then checking.."
16645         for file in $(find $migrate_dir); do
16646                 mdt_index=$($LFS getstripe -m $file)
16647                 if [ $mdt_index -lt $new_index ] ||
16648                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16649                         error "$file is on MDT$mdt_index"
16650                 fi
16651         done
16652
16653         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16654 }
16655 run_test 230d "check migrate big directory"
16656
16657 test_230e() {
16658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16659         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16660         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16661                 skip "Need MDS version at least 2.11.52"
16662
16663         local i
16664         local j
16665         local a_fid
16666         local b_fid
16667
16668         mkdir -p $DIR/$tdir
16669         mkdir $DIR/$tdir/migrate_dir
16670         mkdir $DIR/$tdir/other_dir
16671         touch $DIR/$tdir/migrate_dir/a
16672         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16673         ls $DIR/$tdir/other_dir
16674
16675         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16676                 error "migrate dir fails"
16677
16678         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16679         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16680
16681         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16682         [ $mdt_index == 0 ] || error "a is not on MDT0"
16683
16684         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16685                 error "migrate dir fails"
16686
16687         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16688         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16689
16690         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16691         [ $mdt_index == 1 ] || error "a is not on MDT1"
16692
16693         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16694         [ $mdt_index == 1 ] || error "b is not on MDT1"
16695
16696         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16697         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16698
16699         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16700
16701         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16702 }
16703 run_test 230e "migrate mulitple local link files"
16704
16705 test_230f() {
16706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16707         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16708         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16709                 skip "Need MDS version at least 2.11.52"
16710
16711         local a_fid
16712         local ln_fid
16713
16714         mkdir -p $DIR/$tdir
16715         mkdir $DIR/$tdir/migrate_dir
16716         $LFS mkdir -i1 $DIR/$tdir/other_dir
16717         touch $DIR/$tdir/migrate_dir/a
16718         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16719         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16720         ls $DIR/$tdir/other_dir
16721
16722         # a should be migrated to MDT1, since no other links on MDT0
16723         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16724                 error "#1 migrate dir fails"
16725         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16726         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16727         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16728         [ $mdt_index == 1 ] || error "a is not on MDT1"
16729
16730         # a should stay on MDT1, because it is a mulitple link file
16731         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16732                 error "#2 migrate dir fails"
16733         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16734         [ $mdt_index == 1 ] || error "a is not on MDT1"
16735
16736         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16737                 error "#3 migrate dir fails"
16738
16739         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16740         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16741         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16742
16743         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16744         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16745
16746         # a should be migrated to MDT0, since no other links on MDT1
16747         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16748                 error "#4 migrate dir fails"
16749         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16750         [ $mdt_index == 0 ] || error "a is not on MDT0"
16751
16752         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16753 }
16754 run_test 230f "migrate mulitple remote link files"
16755
16756 test_230g() {
16757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16758         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16759         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16760                 skip "Need MDS version at least 2.11.52"
16761
16762         mkdir -p $DIR/$tdir/migrate_dir
16763
16764         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16765                 error "migrating dir to non-exist MDT succeeds"
16766         true
16767 }
16768 run_test 230g "migrate dir to non-exist MDT"
16769
16770 test_230h() {
16771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16772         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16773         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16774                 skip "Need MDS version at least 2.11.52"
16775
16776         local mdt_index
16777
16778         mkdir -p $DIR/$tdir/migrate_dir
16779
16780         $LFS migrate -m1 $DIR &&
16781                 error "migrating mountpoint1 should fail"
16782
16783         $LFS migrate -m1 $DIR/$tdir/.. &&
16784                 error "migrating mountpoint2 should fail"
16785
16786         # same as mv
16787         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16788                 error "migrating $tdir/migrate_dir/.. should fail"
16789
16790         true
16791 }
16792 run_test 230h "migrate .. and root"
16793
16794 test_230i() {
16795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16796         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16797         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16798                 skip "Need MDS version at least 2.11.52"
16799
16800         mkdir -p $DIR/$tdir/migrate_dir
16801
16802         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16803                 error "migration fails with a tailing slash"
16804
16805         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16806                 error "migration fails with two tailing slashes"
16807 }
16808 run_test 230i "lfs migrate -m tolerates trailing slashes"
16809
16810 test_230j() {
16811         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16812         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16813                 skip "Need MDS version at least 2.11.52"
16814
16815         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16816         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16817                 error "create $tfile failed"
16818         cat /etc/passwd > $DIR/$tdir/$tfile
16819
16820         $LFS migrate -m 1 $DIR/$tdir
16821
16822         cmp /etc/passwd $DIR/$tdir/$tfile ||
16823                 error "DoM file mismatch after migration"
16824 }
16825 run_test 230j "DoM file data not changed after dir migration"
16826
16827 test_230k() {
16828         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16829         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16830                 skip "Need MDS version at least 2.11.56"
16831
16832         local total=20
16833         local files_on_starting_mdt=0
16834
16835         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16836         $LFS getdirstripe $DIR/$tdir
16837         for i in $(seq $total); do
16838                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16839                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16840                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16841         done
16842
16843         echo "$files_on_starting_mdt files on MDT0"
16844
16845         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16846         $LFS getdirstripe $DIR/$tdir
16847
16848         files_on_starting_mdt=0
16849         for i in $(seq $total); do
16850                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16851                         error "file $tfile.$i mismatch after migration"
16852                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16853                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16854         done
16855
16856         echo "$files_on_starting_mdt files on MDT1 after migration"
16857         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16858
16859         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16860         $LFS getdirstripe $DIR/$tdir
16861
16862         files_on_starting_mdt=0
16863         for i in $(seq $total); do
16864                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16865                         error "file $tfile.$i mismatch after 2nd migration"
16866                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16867                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16868         done
16869
16870         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16871         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16872
16873         true
16874 }
16875 run_test 230k "file data not changed after dir migration"
16876
16877 test_230l() {
16878         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16879         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16880                 skip "Need MDS version at least 2.11.56"
16881
16882         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16883         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16884                 error "create files under remote dir failed $i"
16885         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16886 }
16887 run_test 230l "readdir between MDTs won't crash"
16888
16889 test_231a()
16890 {
16891         # For simplicity this test assumes that max_pages_per_rpc
16892         # is the same across all OSCs
16893         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16894         local bulk_size=$((max_pages * PAGE_SIZE))
16895         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16896                                        head -n 1)
16897
16898         mkdir -p $DIR/$tdir
16899         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16900                 error "failed to set stripe with -S ${brw_size}M option"
16901
16902         # clear the OSC stats
16903         $LCTL set_param osc.*.stats=0 &>/dev/null
16904         stop_writeback
16905
16906         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
16907         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
16908                 oflag=direct &>/dev/null || error "dd failed"
16909
16910         sync; sleep 1; sync # just to be safe
16911         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
16912         if [ x$nrpcs != "x1" ]; then
16913                 $LCTL get_param osc.*.stats
16914                 error "found $nrpcs ost_write RPCs, not 1 as expected"
16915         fi
16916
16917         start_writeback
16918         # Drop the OSC cache, otherwise we will read from it
16919         cancel_lru_locks osc
16920
16921         # clear the OSC stats
16922         $LCTL set_param osc.*.stats=0 &>/dev/null
16923
16924         # Client reads $bulk_size.
16925         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
16926                 iflag=direct &>/dev/null || error "dd failed"
16927
16928         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
16929         if [ x$nrpcs != "x1" ]; then
16930                 $LCTL get_param osc.*.stats
16931                 error "found $nrpcs ost_read RPCs, not 1 as expected"
16932         fi
16933 }
16934 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
16935
16936 test_231b() {
16937         mkdir -p $DIR/$tdir
16938         local i
16939         for i in {0..1023}; do
16940                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
16941                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
16942                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
16943         done
16944         sync
16945 }
16946 run_test 231b "must not assert on fully utilized OST request buffer"
16947
16948 test_232a() {
16949         mkdir -p $DIR/$tdir
16950         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16951
16952         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16953         do_facet ost1 $LCTL set_param fail_loc=0x31c
16954
16955         # ignore dd failure
16956         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
16957
16958         do_facet ost1 $LCTL set_param fail_loc=0
16959         umount_client $MOUNT || error "umount failed"
16960         mount_client $MOUNT || error "mount failed"
16961         stop ost1 || error "cannot stop ost1"
16962         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16963 }
16964 run_test 232a "failed lock should not block umount"
16965
16966 test_232b() {
16967         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
16968                 skip "Need MDS version at least 2.10.58"
16969
16970         mkdir -p $DIR/$tdir
16971         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16972         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
16973         sync
16974         cancel_lru_locks osc
16975
16976         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16977         do_facet ost1 $LCTL set_param fail_loc=0x31c
16978
16979         # ignore failure
16980         $LFS data_version $DIR/$tdir/$tfile || true
16981
16982         do_facet ost1 $LCTL set_param fail_loc=0
16983         umount_client $MOUNT || error "umount failed"
16984         mount_client $MOUNT || error "mount failed"
16985         stop ost1 || error "cannot stop ost1"
16986         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16987 }
16988 run_test 232b "failed data version lock should not block umount"
16989
16990 test_233a() {
16991         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
16992                 skip "Need MDS version at least 2.3.64"
16993         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16994
16995         local fid=$($LFS path2fid $MOUNT)
16996
16997         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16998                 error "cannot access $MOUNT using its FID '$fid'"
16999 }
17000 run_test 233a "checking that OBF of the FS root succeeds"
17001
17002 test_233b() {
17003         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
17004                 skip "Need MDS version at least 2.5.90"
17005         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17006
17007         local fid=$($LFS path2fid $MOUNT/.lustre)
17008
17009         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17010                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
17011
17012         fid=$($LFS path2fid $MOUNT/.lustre/fid)
17013         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17014                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
17015 }
17016 run_test 233b "checking that OBF of the FS .lustre succeeds"
17017
17018 test_234() {
17019         local p="$TMP/sanityN-$TESTNAME.parameters"
17020         save_lustre_params client "llite.*.xattr_cache" > $p
17021         lctl set_param llite.*.xattr_cache 1 ||
17022                 skip_env "xattr cache is not supported"
17023
17024         mkdir -p $DIR/$tdir || error "mkdir failed"
17025         touch $DIR/$tdir/$tfile || error "touch failed"
17026         # OBD_FAIL_LLITE_XATTR_ENOMEM
17027         $LCTL set_param fail_loc=0x1405
17028         getfattr -n user.attr $DIR/$tdir/$tfile &&
17029                 error "getfattr should have failed with ENOMEM"
17030         $LCTL set_param fail_loc=0x0
17031         rm -rf $DIR/$tdir
17032
17033         restore_lustre_params < $p
17034         rm -f $p
17035 }
17036 run_test 234 "xattr cache should not crash on ENOMEM"
17037
17038 test_235() {
17039         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
17040                 skip "Need MDS version at least 2.4.52"
17041
17042         flock_deadlock $DIR/$tfile
17043         local RC=$?
17044         case $RC in
17045                 0)
17046                 ;;
17047                 124) error "process hangs on a deadlock"
17048                 ;;
17049                 *) error "error executing flock_deadlock $DIR/$tfile"
17050                 ;;
17051         esac
17052 }
17053 run_test 235 "LU-1715: flock deadlock detection does not work properly"
17054
17055 #LU-2935
17056 test_236() {
17057         check_swap_layouts_support
17058
17059         local ref1=/etc/passwd
17060         local ref2=/etc/group
17061         local file1=$DIR/$tdir/f1
17062         local file2=$DIR/$tdir/f2
17063
17064         test_mkdir -c1 $DIR/$tdir
17065         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
17066         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
17067         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
17068         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
17069         local fd=$(free_fd)
17070         local cmd="exec $fd<>$file2"
17071         eval $cmd
17072         rm $file2
17073         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
17074                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
17075         cmd="exec $fd>&-"
17076         eval $cmd
17077         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17078
17079         #cleanup
17080         rm -rf $DIR/$tdir
17081 }
17082 run_test 236 "Layout swap on open unlinked file"
17083
17084 # LU-4659 linkea consistency
17085 test_238() {
17086         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17087                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17088                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17089                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17090
17091         touch $DIR/$tfile
17092         ln $DIR/$tfile $DIR/$tfile.lnk
17093         touch $DIR/$tfile.new
17094         mv $DIR/$tfile.new $DIR/$tfile
17095         local fid1=$($LFS path2fid $DIR/$tfile)
17096         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
17097         local path1=$($LFS fid2path $FSNAME "$fid1")
17098         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
17099         local path2=$($LFS fid2path $FSNAME "$fid2")
17100         [ $tfile.lnk == $path2 ] ||
17101                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
17102         rm -f $DIR/$tfile*
17103 }
17104 run_test 238 "Verify linkea consistency"
17105
17106 test_239A() { # was test_239
17107         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
17108                 skip "Need MDS version at least 2.5.60"
17109
17110         local list=$(comma_list $(mdts_nodes))
17111
17112         mkdir -p $DIR/$tdir
17113         createmany -o $DIR/$tdir/f- 5000
17114         unlinkmany $DIR/$tdir/f- 5000
17115         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
17116                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
17117         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
17118                         osp.*MDT*.sync_in_flight" | calc_sum)
17119         [ "$changes" -eq 0 ] || error "$changes not synced"
17120 }
17121 run_test 239A "osp_sync test"
17122
17123 test_239a() { #LU-5297
17124         remote_mds_nodsh && skip "remote MDS with nodsh"
17125
17126         touch $DIR/$tfile
17127         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
17128         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
17129         chgrp $RUNAS_GID $DIR/$tfile
17130         wait_delete_completed
17131 }
17132 run_test 239a "process invalid osp sync record correctly"
17133
17134 test_239b() { #LU-5297
17135         remote_mds_nodsh && skip "remote MDS with nodsh"
17136
17137         touch $DIR/$tfile1
17138         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
17139         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
17140         chgrp $RUNAS_GID $DIR/$tfile1
17141         wait_delete_completed
17142         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17143         touch $DIR/$tfile2
17144         chgrp $RUNAS_GID $DIR/$tfile2
17145         wait_delete_completed
17146 }
17147 run_test 239b "process osp sync record with ENOMEM error correctly"
17148
17149 test_240() {
17150         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17151         remote_mds_nodsh && skip "remote MDS with nodsh"
17152
17153         mkdir -p $DIR/$tdir
17154
17155         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
17156                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
17157         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
17158                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
17159
17160         umount_client $MOUNT || error "umount failed"
17161         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
17162         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
17163         mount_client $MOUNT || error "failed to mount client"
17164
17165         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
17166         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
17167 }
17168 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
17169
17170 test_241_bio() {
17171         local count=$1
17172         local bsize=$2
17173
17174         for LOOP in $(seq $count); do
17175                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
17176                 cancel_lru_locks $OSC || true
17177         done
17178 }
17179
17180 test_241_dio() {
17181         local count=$1
17182         local bsize=$2
17183
17184         for LOOP in $(seq $1); do
17185                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
17186                         2>/dev/null
17187         done
17188 }
17189
17190 test_241a() { # was test_241
17191         local bsize=$PAGE_SIZE
17192
17193         (( bsize < 40960 )) && bsize=40960
17194         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17195         ls -la $DIR/$tfile
17196         cancel_lru_locks $OSC
17197         test_241_bio 1000 $bsize &
17198         PID=$!
17199         test_241_dio 1000 $bsize
17200         wait $PID
17201 }
17202 run_test 241a "bio vs dio"
17203
17204 test_241b() {
17205         local bsize=$PAGE_SIZE
17206
17207         (( bsize < 40960 )) && bsize=40960
17208         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17209         ls -la $DIR/$tfile
17210         test_241_dio 1000 $bsize &
17211         PID=$!
17212         test_241_dio 1000 $bsize
17213         wait $PID
17214 }
17215 run_test 241b "dio vs dio"
17216
17217 test_242() {
17218         remote_mds_nodsh && skip "remote MDS with nodsh"
17219
17220         mkdir -p $DIR/$tdir
17221         touch $DIR/$tdir/$tfile
17222
17223         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
17224         do_facet mds1 lctl set_param fail_loc=0x105
17225         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
17226
17227         do_facet mds1 lctl set_param fail_loc=0
17228         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
17229 }
17230 run_test 242 "mdt_readpage failure should not cause directory unreadable"
17231
17232 test_243()
17233 {
17234         test_mkdir $DIR/$tdir
17235         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
17236 }
17237 run_test 243 "various group lock tests"
17238
17239 test_244a()
17240 {
17241         test_mkdir $DIR/$tdir
17242         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
17243         sendfile_grouplock $DIR/$tdir/$tfile || \
17244                 error "sendfile+grouplock failed"
17245         rm -rf $DIR/$tdir
17246 }
17247 run_test 244a "sendfile with group lock tests"
17248
17249 test_244b()
17250 {
17251         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17252
17253         local threads=50
17254         local size=$((1024*1024))
17255
17256         test_mkdir $DIR/$tdir
17257         for i in $(seq 1 $threads); do
17258                 local file=$DIR/$tdir/file_$((i / 10))
17259                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
17260                 local pids[$i]=$!
17261         done
17262         for i in $(seq 1 $threads); do
17263                 wait ${pids[$i]}
17264         done
17265 }
17266 run_test 244b "multi-threaded write with group lock"
17267
17268 test_245() {
17269         local flagname="multi_mod_rpcs"
17270         local connect_data_name="max_mod_rpcs"
17271         local out
17272
17273         # check if multiple modify RPCs flag is set
17274         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
17275                 grep "connect_flags:")
17276         echo "$out"
17277
17278         echo "$out" | grep -qw $flagname
17279         if [ $? -ne 0 ]; then
17280                 echo "connect flag $flagname is not set"
17281                 return
17282         fi
17283
17284         # check if multiple modify RPCs data is set
17285         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
17286         echo "$out"
17287
17288         echo "$out" | grep -qw $connect_data_name ||
17289                 error "import should have connect data $connect_data_name"
17290 }
17291 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
17292
17293 test_246() { # LU-7371
17294         remote_ost_nodsh && skip "remote OST with nodsh"
17295         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
17296                 skip "Need OST version >= 2.7.62"
17297
17298         do_facet ost1 $LCTL set_param fail_val=4095
17299 #define OBD_FAIL_OST_READ_SIZE          0x234
17300         do_facet ost1 $LCTL set_param fail_loc=0x234
17301         $LFS setstripe $DIR/$tfile -i 0 -c 1
17302         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
17303         cancel_lru_locks $FSNAME-OST0000
17304         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
17305 }
17306 run_test 246 "Read file of size 4095 should return right length"
17307
17308 cleanup_247() {
17309         local submount=$1
17310
17311         trap 0
17312         umount_client $submount
17313         rmdir $submount
17314 }
17315
17316 test_247a() {
17317         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17318                 grep -q subtree ||
17319                 skip_env "Fileset feature is not supported"
17320
17321         local submount=${MOUNT}_$tdir
17322
17323         mkdir $MOUNT/$tdir
17324         mkdir -p $submount || error "mkdir $submount failed"
17325         FILESET="$FILESET/$tdir" mount_client $submount ||
17326                 error "mount $submount failed"
17327         trap "cleanup_247 $submount" EXIT
17328         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
17329         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
17330                 error "read $MOUNT/$tdir/$tfile failed"
17331         cleanup_247 $submount
17332 }
17333 run_test 247a "mount subdir as fileset"
17334
17335 test_247b() {
17336         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17337                 skip_env "Fileset feature is not supported"
17338
17339         local submount=${MOUNT}_$tdir
17340
17341         rm -rf $MOUNT/$tdir
17342         mkdir -p $submount || error "mkdir $submount failed"
17343         SKIP_FILESET=1
17344         FILESET="$FILESET/$tdir" mount_client $submount &&
17345                 error "mount $submount should fail"
17346         rmdir $submount
17347 }
17348 run_test 247b "mount subdir that dose not exist"
17349
17350 test_247c() {
17351         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17352                 skip_env "Fileset feature is not supported"
17353
17354         local submount=${MOUNT}_$tdir
17355
17356         mkdir -p $MOUNT/$tdir/dir1
17357         mkdir -p $submount || error "mkdir $submount failed"
17358         trap "cleanup_247 $submount" EXIT
17359         FILESET="$FILESET/$tdir" mount_client $submount ||
17360                 error "mount $submount failed"
17361         local fid=$($LFS path2fid $MOUNT/)
17362         $LFS fid2path $submount $fid && error "fid2path should fail"
17363         cleanup_247 $submount
17364 }
17365 run_test 247c "running fid2path outside root"
17366
17367 test_247d() {
17368         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17369                 skip "Fileset feature is not supported"
17370
17371         local submount=${MOUNT}_$tdir
17372
17373         mkdir -p $MOUNT/$tdir/dir1
17374         mkdir -p $submount || error "mkdir $submount failed"
17375         FILESET="$FILESET/$tdir" mount_client $submount ||
17376                 error "mount $submount failed"
17377         trap "cleanup_247 $submount" EXIT
17378         local fid=$($LFS path2fid $submount/dir1)
17379         $LFS fid2path $submount $fid || error "fid2path should succeed"
17380         cleanup_247 $submount
17381 }
17382 run_test 247d "running fid2path inside root"
17383
17384 # LU-8037
17385 test_247e() {
17386         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17387                 grep -q subtree ||
17388                 skip "Fileset feature is not supported"
17389
17390         local submount=${MOUNT}_$tdir
17391
17392         mkdir $MOUNT/$tdir
17393         mkdir -p $submount || error "mkdir $submount failed"
17394         FILESET="$FILESET/.." mount_client $submount &&
17395                 error "mount $submount should fail"
17396         rmdir $submount
17397 }
17398 run_test 247e "mount .. as fileset"
17399
17400 test_248() {
17401         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
17402         [ -z "$fast_read_sav" ] && skip "no fast read support"
17403
17404         # create a large file for fast read verification
17405         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
17406
17407         # make sure the file is created correctly
17408         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
17409                 { rm -f $DIR/$tfile; skip "file creation error"; }
17410
17411         echo "Test 1: verify that fast read is 4 times faster on cache read"
17412
17413         # small read with fast read enabled
17414         $LCTL set_param -n llite.*.fast_read=1
17415         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17416                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17417                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17418         # small read with fast read disabled
17419         $LCTL set_param -n llite.*.fast_read=0
17420         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17421                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17422                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17423
17424         # verify that fast read is 4 times faster for cache read
17425         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
17426                 error_not_in_vm "fast read was not 4 times faster: " \
17427                            "$t_fast vs $t_slow"
17428
17429         echo "Test 2: verify the performance between big and small read"
17430         $LCTL set_param -n llite.*.fast_read=1
17431
17432         # 1k non-cache read
17433         cancel_lru_locks osc
17434         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17435                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17436                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17437
17438         # 1M non-cache read
17439         cancel_lru_locks osc
17440         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17441                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17442                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17443
17444         # verify that big IO is not 4 times faster than small IO
17445         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
17446                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
17447
17448         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
17449         rm -f $DIR/$tfile
17450 }
17451 run_test 248 "fast read verification"
17452
17453 test_249() { # LU-7890
17454         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
17455                 skip "Need at least version 2.8.54"
17456
17457         rm -f $DIR/$tfile
17458         $LFS setstripe -c 1 $DIR/$tfile
17459         # Offset 2T == 4k * 512M
17460         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
17461                 error "dd to 2T offset failed"
17462 }
17463 run_test 249 "Write above 2T file size"
17464
17465 test_250() {
17466         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
17467          && skip "no 16TB file size limit on ZFS"
17468
17469         $LFS setstripe -c 1 $DIR/$tfile
17470         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
17471         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
17472         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
17473         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
17474                 conv=notrunc,fsync && error "append succeeded"
17475         return 0
17476 }
17477 run_test 250 "Write above 16T limit"
17478
17479 test_251() {
17480         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
17481
17482         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
17483         #Skip once - writing the first stripe will succeed
17484         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17485         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
17486                 error "short write happened"
17487
17488         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17489         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
17490                 error "short read happened"
17491
17492         rm -f $DIR/$tfile
17493 }
17494 run_test 251 "Handling short read and write correctly"
17495
17496 test_252() {
17497         remote_mds_nodsh && skip "remote MDS with nodsh"
17498         remote_ost_nodsh && skip "remote OST with nodsh"
17499         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
17500                 skip_env "ldiskfs only test"
17501         fi
17502
17503         local tgt
17504         local dev
17505         local out
17506         local uuid
17507         local num
17508         local gen
17509
17510         # check lr_reader on OST0000
17511         tgt=ost1
17512         dev=$(facet_device $tgt)
17513         out=$(do_facet $tgt $LR_READER $dev)
17514         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17515         echo "$out"
17516         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
17517         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
17518                 error "Invalid uuid returned by $LR_READER on target $tgt"
17519         echo -e "uuid returned by $LR_READER is '$uuid'\n"
17520
17521         # check lr_reader -c on MDT0000
17522         tgt=mds1
17523         dev=$(facet_device $tgt)
17524         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
17525                 skip "$LR_READER does not support additional options"
17526         fi
17527         out=$(do_facet $tgt $LR_READER -c $dev)
17528         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17529         echo "$out"
17530         num=$(echo "$out" | grep -c "mdtlov")
17531         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
17532                 error "Invalid number of mdtlov clients returned by $LR_READER"
17533         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
17534
17535         # check lr_reader -cr on MDT0000
17536         out=$(do_facet $tgt $LR_READER -cr $dev)
17537         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17538         echo "$out"
17539         echo "$out" | grep -q "^reply_data:$" ||
17540                 error "$LR_READER should have returned 'reply_data' section"
17541         num=$(echo "$out" | grep -c "client_generation")
17542         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
17543 }
17544 run_test 252 "check lr_reader tool"
17545
17546 test_253() {
17547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17548         remote_mds_nodsh && skip "remote MDS with nodsh"
17549         remote_mgs_nodsh && skip "remote MGS with nodsh"
17550
17551         local ostidx=0
17552         local rc=0
17553         local ost_name=$(ostname_from_index $ostidx)
17554
17555         # on the mdt's osc
17556         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
17557         do_facet $SINGLEMDS $LCTL get_param -n \
17558                 osp.$mdtosc_proc1.reserved_mb_high ||
17559                 skip  "remote MDS does not support reserved_mb_high"
17560
17561         rm -rf $DIR/$tdir
17562         wait_mds_ost_sync
17563         wait_delete_completed
17564         mkdir $DIR/$tdir
17565
17566         pool_add $TESTNAME || error "Pool creation failed"
17567         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
17568
17569         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
17570                 error "Setstripe failed"
17571
17572         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
17573
17574         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
17575                     grep "watermarks")
17576         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
17577
17578         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17579                         osp.$mdtosc_proc1.prealloc_status)
17580         echo "prealloc_status $oa_status"
17581
17582         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
17583                 error "File creation should fail"
17584
17585         #object allocation was stopped, but we still able to append files
17586         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
17587                 oflag=append || error "Append failed"
17588
17589         rm -f $DIR/$tdir/$tfile.0
17590
17591         # For this test, we want to delete the files we created to go out of
17592         # space but leave the watermark, so we remain nearly out of space
17593         ost_watermarks_enospc_delete_files $tfile $ostidx
17594
17595         wait_delete_completed
17596
17597         sleep_maxage
17598
17599         for i in $(seq 10 12); do
17600                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
17601                         2>/dev/null || error "File creation failed after rm"
17602         done
17603
17604         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17605                         osp.$mdtosc_proc1.prealloc_status)
17606         echo "prealloc_status $oa_status"
17607
17608         if (( oa_status != 0 )); then
17609                 error "Object allocation still disable after rm"
17610         fi
17611 }
17612 run_test 253 "Check object allocation limit"
17613
17614 test_254() {
17615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17616         remote_mds_nodsh && skip "remote MDS with nodsh"
17617         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17618                 skip "MDS does not support changelog_size"
17619
17620         local cl_user
17621         local MDT0=$(facet_svc $SINGLEMDS)
17622
17623         changelog_register || error "changelog_register failed"
17624
17625         changelog_clear 0 || error "changelog_clear failed"
17626
17627         local size1=$(do_facet $SINGLEMDS \
17628                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17629         echo "Changelog size $size1"
17630
17631         rm -rf $DIR/$tdir
17632         $LFS mkdir -i 0 $DIR/$tdir
17633         # change something
17634         mkdir -p $DIR/$tdir/pics/2008/zachy
17635         touch $DIR/$tdir/pics/2008/zachy/timestamp
17636         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17637         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17638         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17639         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17640         rm $DIR/$tdir/pics/desktop.jpg
17641
17642         local size2=$(do_facet $SINGLEMDS \
17643                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17644         echo "Changelog size after work $size2"
17645
17646         (( $size2 > $size1 )) ||
17647                 error "new Changelog size=$size2 less than old size=$size1"
17648 }
17649 run_test 254 "Check changelog size"
17650
17651 ladvise_no_type()
17652 {
17653         local type=$1
17654         local file=$2
17655
17656         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17657                 awk -F: '{print $2}' | grep $type > /dev/null
17658         if [ $? -ne 0 ]; then
17659                 return 0
17660         fi
17661         return 1
17662 }
17663
17664 ladvise_no_ioctl()
17665 {
17666         local file=$1
17667
17668         lfs ladvise -a willread $file > /dev/null 2>&1
17669         if [ $? -eq 0 ]; then
17670                 return 1
17671         fi
17672
17673         lfs ladvise -a willread $file 2>&1 |
17674                 grep "Inappropriate ioctl for device" > /dev/null
17675         if [ $? -eq 0 ]; then
17676                 return 0
17677         fi
17678         return 1
17679 }
17680
17681 percent() {
17682         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17683 }
17684
17685 # run a random read IO workload
17686 # usage: random_read_iops <filename> <filesize> <iosize>
17687 random_read_iops() {
17688         local file=$1
17689         local fsize=$2
17690         local iosize=${3:-4096}
17691
17692         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17693                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17694 }
17695
17696 drop_file_oss_cache() {
17697         local file="$1"
17698         local nodes="$2"
17699
17700         $LFS ladvise -a dontneed $file 2>/dev/null ||
17701                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17702 }
17703
17704 ladvise_willread_performance()
17705 {
17706         local repeat=10
17707         local average_origin=0
17708         local average_cache=0
17709         local average_ladvise=0
17710
17711         for ((i = 1; i <= $repeat; i++)); do
17712                 echo "Iter $i/$repeat: reading without willread hint"
17713                 cancel_lru_locks osc
17714                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17715                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17716                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17717                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17718
17719                 cancel_lru_locks osc
17720                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17721                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17722                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17723
17724                 cancel_lru_locks osc
17725                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17726                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17727                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17728                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17729                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17730         done
17731         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17732         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17733         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17734
17735         speedup_cache=$(percent $average_cache $average_origin)
17736         speedup_ladvise=$(percent $average_ladvise $average_origin)
17737
17738         echo "Average uncached read: $average_origin"
17739         echo "Average speedup with OSS cached read: " \
17740                 "$average_cache = +$speedup_cache%"
17741         echo "Average speedup with ladvise willread: " \
17742                 "$average_ladvise = +$speedup_ladvise%"
17743
17744         local lowest_speedup=20
17745         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17746                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17747                         "got $average_cache%. Skipping ladvise willread check."
17748                 return 0
17749         fi
17750
17751         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17752         # it is still good to run until then to exercise 'ladvise willread'
17753         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17754                 [ "$ost1_FSTYPE" = "zfs" ] &&
17755                 echo "osd-zfs does not support dontneed or drop_caches" &&
17756                 return 0
17757
17758         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17759         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17760                 error_not_in_vm "Speedup with willread is less than " \
17761                         "$lowest_speedup%, got $average_ladvise%"
17762 }
17763
17764 test_255a() {
17765         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17766                 skip "lustre < 2.8.54 does not support ladvise "
17767         remote_ost_nodsh && skip "remote OST with nodsh"
17768
17769         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17770
17771         ladvise_no_type willread $DIR/$tfile &&
17772                 skip "willread ladvise is not supported"
17773
17774         ladvise_no_ioctl $DIR/$tfile &&
17775                 skip "ladvise ioctl is not supported"
17776
17777         local size_mb=100
17778         local size=$((size_mb * 1048576))
17779         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17780                 error "dd to $DIR/$tfile failed"
17781
17782         lfs ladvise -a willread $DIR/$tfile ||
17783                 error "Ladvise failed with no range argument"
17784
17785         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17786                 error "Ladvise failed with no -l or -e argument"
17787
17788         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17789                 error "Ladvise failed with only -e argument"
17790
17791         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17792                 error "Ladvise failed with only -l argument"
17793
17794         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17795                 error "End offset should not be smaller than start offset"
17796
17797         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17798                 error "End offset should not be equal to start offset"
17799
17800         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17801                 error "Ladvise failed with overflowing -s argument"
17802
17803         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17804                 error "Ladvise failed with overflowing -e argument"
17805
17806         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17807                 error "Ladvise failed with overflowing -l argument"
17808
17809         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17810                 error "Ladvise succeeded with conflicting -l and -e arguments"
17811
17812         echo "Synchronous ladvise should wait"
17813         local delay=4
17814 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17815         do_nodes $(comma_list $(osts_nodes)) \
17816                 $LCTL set_param fail_val=$delay fail_loc=0x237
17817
17818         local start_ts=$SECONDS
17819         lfs ladvise -a willread $DIR/$tfile ||
17820                 error "Ladvise failed with no range argument"
17821         local end_ts=$SECONDS
17822         local inteval_ts=$((end_ts - start_ts))
17823
17824         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17825                 error "Synchronous advice didn't wait reply"
17826         fi
17827
17828         echo "Asynchronous ladvise shouldn't wait"
17829         local start_ts=$SECONDS
17830         lfs ladvise -a willread -b $DIR/$tfile ||
17831                 error "Ladvise failed with no range argument"
17832         local end_ts=$SECONDS
17833         local inteval_ts=$((end_ts - start_ts))
17834
17835         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17836                 error "Asynchronous advice blocked"
17837         fi
17838
17839         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
17840         ladvise_willread_performance
17841 }
17842 run_test 255a "check 'lfs ladvise -a willread'"
17843
17844 facet_meminfo() {
17845         local facet=$1
17846         local info=$2
17847
17848         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
17849 }
17850
17851 test_255b() {
17852         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17853                 skip "lustre < 2.8.54 does not support ladvise "
17854         remote_ost_nodsh && skip "remote OST with nodsh"
17855
17856         lfs setstripe -c 1 -i 0 $DIR/$tfile
17857
17858         ladvise_no_type dontneed $DIR/$tfile &&
17859                 skip "dontneed ladvise is not supported"
17860
17861         ladvise_no_ioctl $DIR/$tfile &&
17862                 skip "ladvise ioctl is not supported"
17863
17864         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17865                 [ "$ost1_FSTYPE" = "zfs" ] &&
17866                 skip "zfs-osd does not support 'ladvise dontneed'"
17867
17868         local size_mb=100
17869         local size=$((size_mb * 1048576))
17870         # In order to prevent disturbance of other processes, only check 3/4
17871         # of the memory usage
17872         local kibibytes=$((size_mb * 1024 * 3 / 4))
17873
17874         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17875                 error "dd to $DIR/$tfile failed"
17876
17877         #force write to complete before dropping OST cache & checking memory
17878         sync
17879
17880         local total=$(facet_meminfo ost1 MemTotal)
17881         echo "Total memory: $total KiB"
17882
17883         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
17884         local before_read=$(facet_meminfo ost1 Cached)
17885         echo "Cache used before read: $before_read KiB"
17886
17887         lfs ladvise -a willread $DIR/$tfile ||
17888                 error "Ladvise willread failed"
17889         local after_read=$(facet_meminfo ost1 Cached)
17890         echo "Cache used after read: $after_read KiB"
17891
17892         lfs ladvise -a dontneed $DIR/$tfile ||
17893                 error "Ladvise dontneed again failed"
17894         local no_read=$(facet_meminfo ost1 Cached)
17895         echo "Cache used after dontneed ladvise: $no_read KiB"
17896
17897         if [ $total -lt $((before_read + kibibytes)) ]; then
17898                 echo "Memory is too small, abort checking"
17899                 return 0
17900         fi
17901
17902         if [ $((before_read + kibibytes)) -gt $after_read ]; then
17903                 error "Ladvise willread should use more memory" \
17904                         "than $kibibytes KiB"
17905         fi
17906
17907         if [ $((no_read + kibibytes)) -gt $after_read ]; then
17908                 error "Ladvise dontneed should release more memory" \
17909                         "than $kibibytes KiB"
17910         fi
17911 }
17912 run_test 255b "check 'lfs ladvise -a dontneed'"
17913
17914 test_255c() {
17915         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
17916                 skip "lustre < 2.10.50 does not support lockahead"
17917
17918         local count
17919         local new_count
17920         local difference
17921         local i
17922         local rc
17923
17924         test_mkdir -p $DIR/$tdir
17925         $LFS setstripe -i 0 -c 1 $DIR/$tdir
17926
17927         #test 10 returns only success/failure
17928         i=10
17929         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17930         rc=$?
17931         if [ $rc -eq 255 ]; then
17932                 error "Ladvise test${i} failed, ${rc}"
17933         fi
17934
17935         #test 11 counts lock enqueue requests, all others count new locks
17936         i=11
17937         count=$(do_facet ost1 \
17938                 $LCTL get_param -n ost.OSS.ost.stats)
17939         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
17940
17941         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17942         rc=$?
17943         if [ $rc -eq 255 ]; then
17944                 error "Ladvise test${i} failed, ${rc}"
17945         fi
17946
17947         new_count=$(do_facet ost1 \
17948                 $LCTL get_param -n ost.OSS.ost.stats)
17949         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
17950                    awk '{ print $2 }')
17951
17952         difference="$((new_count - count))"
17953         if [ $difference -ne $rc ]; then
17954                 error "Ladvise test${i}, bad enqueue count, returned " \
17955                       "${rc}, actual ${difference}"
17956         fi
17957
17958         for i in $(seq 12 21); do
17959                 # If we do not do this, we run the risk of having too many
17960                 # locks and starting lock cancellation while we are checking
17961                 # lock counts.
17962                 cancel_lru_locks osc
17963
17964                 count=$($LCTL get_param -n \
17965                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17966
17967                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
17968                 rc=$?
17969                 if [ $rc -eq 255 ]; then
17970                         error "Ladvise test ${i} failed, ${rc}"
17971                 fi
17972
17973                 new_count=$($LCTL get_param -n \
17974                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17975                 difference="$((new_count - count))"
17976
17977                 # Test 15 output is divided by 100 to map down to valid return
17978                 if [ $i -eq 15 ]; then
17979                         rc="$((rc * 100))"
17980                 fi
17981
17982                 if [ $difference -ne $rc ]; then
17983                         error "Ladvise test ${i}, bad lock count, returned " \
17984                               "${rc}, actual ${difference}"
17985                 fi
17986         done
17987
17988         #test 22 returns only success/failure
17989         i=22
17990         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17991         rc=$?
17992         if [ $rc -eq 255 ]; then
17993                 error "Ladvise test${i} failed, ${rc}"
17994         fi
17995 }
17996 run_test 255c "suite of ladvise lockahead tests"
17997
17998 test_256() {
17999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18000         remote_mds_nodsh && skip "remote MDS with nodsh"
18001         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18002         changelog_users $SINGLEMDS | grep "^cl" &&
18003                 skip "active changelog user"
18004
18005         local cl_user
18006         local cat_sl
18007         local mdt_dev
18008
18009         mdt_dev=$(mdsdevname 1)
18010         echo $mdt_dev
18011
18012         changelog_register || error "changelog_register failed"
18013
18014         rm -rf $DIR/$tdir
18015         mkdir -p $DIR/$tdir
18016
18017         changelog_clear 0 || error "changelog_clear failed"
18018
18019         # change something
18020         touch $DIR/$tdir/{1..10}
18021
18022         # stop the MDT
18023         stop $SINGLEMDS || error "Fail to stop MDT"
18024
18025         # remount the MDT
18026
18027         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
18028
18029         #after mount new plainllog is used
18030         touch $DIR/$tdir/{11..19}
18031         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
18032         stack_trap "rm -f $tmpfile"
18033         cat_sl=$(do_facet $SINGLEMDS "sync; \
18034                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18035                  llog_reader $tmpfile | grep -c type=1064553b")
18036         do_facet $SINGLEMDS llog_reader $tmpfile
18037
18038         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
18039
18040         changelog_clear 0 || error "changelog_clear failed"
18041
18042         cat_sl=$(do_facet $SINGLEMDS "sync; \
18043                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18044                  llog_reader $tmpfile | grep -c type=1064553b")
18045
18046         if (( cat_sl == 2 )); then
18047                 error "Empty plain llog was not deleted from changelog catalog"
18048         elif (( cat_sl != 1 )); then
18049                 error "Active plain llog shouldn't be deleted from catalog"
18050         fi
18051 }
18052 run_test 256 "Check llog delete for empty and not full state"
18053
18054 test_257() {
18055         remote_mds_nodsh && skip "remote MDS with nodsh"
18056         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
18057                 skip "Need MDS version at least 2.8.55"
18058
18059         test_mkdir $DIR/$tdir
18060
18061         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
18062                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
18063         stat $DIR/$tdir
18064
18065 #define OBD_FAIL_MDS_XATTR_REP                  0x161
18066         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18067         local facet=mds$((mdtidx + 1))
18068         set_nodes_failloc $(facet_active_host $facet) 0x80000161
18069         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
18070
18071         stop $facet || error "stop MDS failed"
18072         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
18073                 error "start MDS fail"
18074         wait_recovery_complete $facet
18075 }
18076 run_test 257 "xattr locks are not lost"
18077
18078 # Verify we take the i_mutex when security requires it
18079 test_258a() {
18080 #define OBD_FAIL_IMUTEX_SEC 0x141c
18081         $LCTL set_param fail_loc=0x141c
18082         touch $DIR/$tfile
18083         chmod u+s $DIR/$tfile
18084         chmod a+rwx $DIR/$tfile
18085         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18086         RC=$?
18087         if [ $RC -ne 0 ]; then
18088                 error "error, failed to take i_mutex, rc=$?"
18089         fi
18090         rm -f $DIR/$tfile
18091 }
18092 run_test 258a "verify i_mutex security behavior when suid attributes is set"
18093
18094 # Verify we do NOT take the i_mutex in the normal case
18095 test_258b() {
18096 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
18097         $LCTL set_param fail_loc=0x141d
18098         touch $DIR/$tfile
18099         chmod a+rwx $DIR
18100         chmod a+rw $DIR/$tfile
18101         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18102         RC=$?
18103         if [ $RC -ne 0 ]; then
18104                 error "error, took i_mutex unnecessarily, rc=$?"
18105         fi
18106         rm -f $DIR/$tfile
18107
18108 }
18109 run_test 258b "verify i_mutex security behavior"
18110
18111 test_259() {
18112         local file=$DIR/$tfile
18113         local before
18114         local after
18115
18116         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18117
18118         stack_trap "rm -f $file" EXIT
18119
18120         wait_delete_completed
18121         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18122         echo "before: $before"
18123
18124         $LFS setstripe -i 0 -c 1 $file
18125         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
18126         sync_all_data
18127         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18128         echo "after write: $after"
18129
18130 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
18131         do_facet ost1 $LCTL set_param fail_loc=0x2301
18132         $TRUNCATE $file 0
18133         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18134         echo "after truncate: $after"
18135
18136         stop ost1
18137         do_facet ost1 $LCTL set_param fail_loc=0
18138         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18139         sleep 2
18140         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18141         echo "after restart: $after"
18142         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
18143                 error "missing truncate?"
18144
18145         return 0
18146 }
18147 run_test 259 "crash at delayed truncate"
18148
18149 test_260() {
18150 #define OBD_FAIL_MDC_CLOSE               0x806
18151         $LCTL set_param fail_loc=0x80000806
18152         touch $DIR/$tfile
18153
18154 }
18155 run_test 260 "Check mdc_close fail"
18156
18157 ### Data-on-MDT sanity tests ###
18158 test_270a() {
18159         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18160                 skip "Need MDS version at least 2.10.55 for DoM"
18161
18162         # create DoM file
18163         local dom=$DIR/$tdir/dom_file
18164         local tmp=$DIR/$tdir/tmp_file
18165
18166         mkdir -p $DIR/$tdir
18167
18168         # basic checks for DoM component creation
18169         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
18170                 error "Can set MDT layout to non-first entry"
18171
18172         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
18173                 error "Can define multiple entries as MDT layout"
18174
18175         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
18176
18177         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
18178         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
18179         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
18180
18181         local mdtidx=$($LFS getstripe -m $dom)
18182         local mdtname=MDT$(printf %04x $mdtidx)
18183         local facet=mds$((mdtidx + 1))
18184         local space_check=1
18185
18186         # Skip free space checks with ZFS
18187         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
18188
18189         # write
18190         sync
18191         local size_tmp=$((65536 * 3))
18192         local mdtfree1=$(do_facet $facet \
18193                          lctl get_param -n osd*.*$mdtname.kbytesfree)
18194
18195         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18196         # check also direct IO along write
18197         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
18198         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18199         sync
18200         cmp $tmp $dom || error "file data is different"
18201         [ $(stat -c%s $dom) == $size_tmp ] ||
18202                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18203         if [ $space_check == 1 ]; then
18204                 local mdtfree2=$(do_facet $facet \
18205                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
18206
18207                 # increase in usage from by $size_tmp
18208                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18209                         error "MDT free space wrong after write: " \
18210                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18211         fi
18212
18213         # truncate
18214         local size_dom=10000
18215
18216         $TRUNCATE $dom $size_dom
18217         [ $(stat -c%s $dom) == $size_dom ] ||
18218                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
18219         if [ $space_check == 1 ]; then
18220                 mdtfree1=$(do_facet $facet \
18221                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18222                 # decrease in usage from $size_tmp to new $size_dom
18223                 [ $(($mdtfree1 - $mdtfree2)) -ge \
18224                   $(((size_tmp - size_dom) / 1024)) ] ||
18225                         error "MDT free space is wrong after truncate: " \
18226                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
18227         fi
18228
18229         # append
18230         cat $tmp >> $dom
18231         sync
18232         size_dom=$((size_dom + size_tmp))
18233         [ $(stat -c%s $dom) == $size_dom ] ||
18234                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
18235         if [ $space_check == 1 ]; then
18236                 mdtfree2=$(do_facet $facet \
18237                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18238                 # increase in usage by $size_tmp from previous
18239                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18240                         error "MDT free space is wrong after append: " \
18241                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18242         fi
18243
18244         # delete
18245         rm $dom
18246         if [ $space_check == 1 ]; then
18247                 mdtfree1=$(do_facet $facet \
18248                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18249                 # decrease in usage by $size_dom from previous
18250                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
18251                         error "MDT free space is wrong after removal: " \
18252                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
18253         fi
18254
18255         # combined striping
18256         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
18257                 error "Can't create DoM + OST striping"
18258
18259         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
18260         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18261         # check also direct IO along write
18262         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18263         sync
18264         cmp $tmp $dom || error "file data is different"
18265         [ $(stat -c%s $dom) == $size_tmp ] ||
18266                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18267         rm $dom $tmp
18268
18269         return 0
18270 }
18271 run_test 270a "DoM: basic functionality tests"
18272
18273 test_270b() {
18274         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18275                 skip "Need MDS version at least 2.10.55"
18276
18277         local dom=$DIR/$tdir/dom_file
18278         local max_size=1048576
18279
18280         mkdir -p $DIR/$tdir
18281         $LFS setstripe -E $max_size -L mdt $dom
18282
18283         # truncate over the limit
18284         $TRUNCATE $dom $(($max_size + 1)) &&
18285                 error "successful truncate over the maximum size"
18286         # write over the limit
18287         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
18288                 error "successful write over the maximum size"
18289         # append over the limit
18290         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
18291         echo "12345" >> $dom && error "successful append over the maximum size"
18292         rm $dom
18293
18294         return 0
18295 }
18296 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
18297
18298 test_270c() {
18299         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18300                 skip "Need MDS version at least 2.10.55"
18301
18302         mkdir -p $DIR/$tdir
18303         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18304
18305         # check files inherit DoM EA
18306         touch $DIR/$tdir/first
18307         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
18308                 error "bad pattern"
18309         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
18310                 error "bad stripe count"
18311         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
18312                 error "bad stripe size"
18313
18314         # check directory inherits DoM EA and uses it as default
18315         mkdir $DIR/$tdir/subdir
18316         touch $DIR/$tdir/subdir/second
18317         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
18318                 error "bad pattern in sub-directory"
18319         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
18320                 error "bad stripe count in sub-directory"
18321         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
18322                 error "bad stripe size in sub-directory"
18323         return 0
18324 }
18325 run_test 270c "DoM: DoM EA inheritance tests"
18326
18327 test_270d() {
18328         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18329                 skip "Need MDS version at least 2.10.55"
18330
18331         mkdir -p $DIR/$tdir
18332         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18333
18334         # inherit default DoM striping
18335         mkdir $DIR/$tdir/subdir
18336         touch $DIR/$tdir/subdir/f1
18337
18338         # change default directory striping
18339         $LFS setstripe -c 1 $DIR/$tdir/subdir
18340         touch $DIR/$tdir/subdir/f2
18341         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
18342                 error "wrong default striping in file 2"
18343         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
18344                 error "bad pattern in file 2"
18345         return 0
18346 }
18347 run_test 270d "DoM: change striping from DoM to RAID0"
18348
18349 test_270e() {
18350         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18351                 skip "Need MDS version at least 2.10.55"
18352
18353         mkdir -p $DIR/$tdir/dom
18354         mkdir -p $DIR/$tdir/norm
18355         DOMFILES=20
18356         NORMFILES=10
18357         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
18358         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
18359
18360         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
18361         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
18362
18363         # find DoM files by layout
18364         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
18365         [ $NUM -eq  $DOMFILES ] ||
18366                 error "lfs find -L: found $NUM, expected $DOMFILES"
18367         echo "Test 1: lfs find 20 DOM files by layout: OK"
18368
18369         # there should be 1 dir with default DOM striping
18370         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
18371         [ $NUM -eq  1 ] ||
18372                 error "lfs find -L: found $NUM, expected 1 dir"
18373         echo "Test 2: lfs find 1 DOM dir by layout: OK"
18374
18375         # find DoM files by stripe size
18376         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
18377         [ $NUM -eq  $DOMFILES ] ||
18378                 error "lfs find -S: found $NUM, expected $DOMFILES"
18379         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
18380
18381         # find files by stripe offset except DoM files
18382         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
18383         [ $NUM -eq  $NORMFILES ] ||
18384                 error "lfs find -i: found $NUM, expected $NORMFILES"
18385         echo "Test 5: lfs find no DOM files by stripe index: OK"
18386         return 0
18387 }
18388 run_test 270e "DoM: lfs find with DoM files test"
18389
18390 test_270f() {
18391         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18392                 skip "Need MDS version at least 2.10.55"
18393
18394         local mdtname=${FSNAME}-MDT0000-mdtlov
18395         local dom=$DIR/$tdir/dom_file
18396         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
18397                                                 lod.$mdtname.dom_stripesize)
18398         local dom_limit=131072
18399
18400         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
18401         local dom_current=$(do_facet mds1 $LCTL get_param -n \
18402                                                 lod.$mdtname.dom_stripesize)
18403         [ ${dom_limit} -eq ${dom_current} ] ||
18404                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
18405
18406         $LFS mkdir -i 0 -c 1 $DIR/$tdir
18407         $LFS setstripe -d $DIR/$tdir
18408         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
18409                 error "Can't set directory default striping"
18410
18411         # exceed maximum stripe size
18412         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18413                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
18414         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
18415                 error "Able to create DoM component size more than LOD limit"
18416
18417         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
18418         dom_current=$(do_facet mds1 $LCTL get_param -n \
18419                                                 lod.$mdtname.dom_stripesize)
18420         [ 0 -eq ${dom_current} ] ||
18421                 error "Can't set zero DoM stripe limit"
18422         rm $dom
18423
18424         # attempt to create DoM file on server with disabled DoM should
18425         # remove DoM entry from layout and be succeed
18426         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
18427                 error "Can't create DoM file (DoM is disabled)"
18428         [ $($LFS getstripe -L $dom) == "mdt" ] &&
18429                 error "File has DoM component while DoM is disabled"
18430         rm $dom
18431
18432         # attempt to create DoM file with only DoM stripe should return error
18433         $LFS setstripe -E $dom_limit -L mdt $dom &&
18434                 error "Able to create DoM-only file while DoM is disabled"
18435
18436         # too low values to be aligned with smallest stripe size 64K
18437         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
18438         dom_current=$(do_facet mds1 $LCTL get_param -n \
18439                                                 lod.$mdtname.dom_stripesize)
18440         [ 30000 -eq ${dom_current} ] &&
18441                 error "Can set too small DoM stripe limit"
18442
18443         # 64K is a minimal stripe size in Lustre, expect limit of that size
18444         [ 65536 -eq ${dom_current} ] ||
18445                 error "Limit is not set to 64K but ${dom_current}"
18446
18447         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
18448         dom_current=$(do_facet mds1 $LCTL get_param -n \
18449                                                 lod.$mdtname.dom_stripesize)
18450         echo $dom_current
18451         [ 2147483648 -eq ${dom_current} ] &&
18452                 error "Can set too large DoM stripe limit"
18453
18454         do_facet mds1 $LCTL set_param -n \
18455                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
18456         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18457                 error "Can't create DoM component size after limit change"
18458         do_facet mds1 $LCTL set_param -n \
18459                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
18460         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
18461                 error "Can't create DoM file after limit decrease"
18462         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
18463                 error "Can create big DoM component after limit decrease"
18464         touch ${dom}_def ||
18465                 error "Can't create file with old default layout"
18466
18467         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
18468         return 0
18469 }
18470 run_test 270f "DoM: maximum DoM stripe size checks"
18471
18472 test_271a() {
18473         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18474                 skip "Need MDS version at least 2.10.55"
18475
18476         local dom=$DIR/$tdir/dom
18477
18478         mkdir -p $DIR/$tdir
18479
18480         $LFS setstripe -E 1024K -L mdt $dom
18481
18482         lctl set_param -n mdc.*.stats=clear
18483         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18484         cat $dom > /dev/null
18485         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
18486         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
18487         ls $dom
18488         rm -f $dom
18489 }
18490 run_test 271a "DoM: data is cached for read after write"
18491
18492 test_271b() {
18493         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18494                 skip "Need MDS version at least 2.10.55"
18495
18496         local dom=$DIR/$tdir/dom
18497
18498         mkdir -p $DIR/$tdir
18499
18500         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18501
18502         lctl set_param -n mdc.*.stats=clear
18503         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18504         cancel_lru_locks mdc
18505         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
18506         # second stat to check size is cached on client
18507         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
18508         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18509         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
18510         rm -f $dom
18511 }
18512 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
18513
18514 test_271ba() {
18515         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18516                 skip "Need MDS version at least 2.10.55"
18517
18518         local dom=$DIR/$tdir/dom
18519
18520         mkdir -p $DIR/$tdir
18521
18522         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18523
18524         lctl set_param -n mdc.*.stats=clear
18525         lctl set_param -n osc.*.stats=clear
18526         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
18527         cancel_lru_locks mdc
18528         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18529         # second stat to check size is cached on client
18530         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18531         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18532         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
18533         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
18534         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
18535         rm -f $dom
18536 }
18537 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
18538
18539
18540 get_mdc_stats() {
18541         local mdtidx=$1
18542         local param=$2
18543         local mdt=MDT$(printf %04x $mdtidx)
18544
18545         if [ -z $param ]; then
18546                 lctl get_param -n mdc.*$mdt*.stats
18547         else
18548                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
18549         fi
18550 }
18551
18552 test_271c() {
18553         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18554                 skip "Need MDS version at least 2.10.55"
18555
18556         local dom=$DIR/$tdir/dom
18557
18558         mkdir -p $DIR/$tdir
18559
18560         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18561
18562         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18563         local facet=mds$((mdtidx + 1))
18564
18565         cancel_lru_locks mdc
18566         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
18567         createmany -o $dom 1000
18568         lctl set_param -n mdc.*.stats=clear
18569         smalliomany -w $dom 1000 200
18570         get_mdc_stats $mdtidx
18571         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18572         # Each file has 1 open, 1 IO enqueues, total 2000
18573         # but now we have also +1 getxattr for security.capability, total 3000
18574         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
18575         unlinkmany $dom 1000
18576
18577         cancel_lru_locks mdc
18578         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
18579         createmany -o $dom 1000
18580         lctl set_param -n mdc.*.stats=clear
18581         smalliomany -w $dom 1000 200
18582         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18583         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
18584         # for OPEN and IO lock.
18585         [ $((enq - enq_2)) -ge 1000 ] ||
18586                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
18587         unlinkmany $dom 1000
18588         return 0
18589 }
18590 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
18591
18592 cleanup_271def_tests() {
18593         trap 0
18594         rm -f $1
18595 }
18596
18597 test_271d() {
18598         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18599                 skip "Need MDS version at least 2.10.57"
18600
18601         local dom=$DIR/$tdir/dom
18602         local tmp=$TMP/$tfile
18603         trap "cleanup_271def_tests $tmp" EXIT
18604
18605         mkdir -p $DIR/$tdir
18606
18607         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18608
18609         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18610
18611         cancel_lru_locks mdc
18612         dd if=/dev/urandom of=$tmp bs=1000 count=1
18613         dd if=$tmp of=$dom bs=1000 count=1
18614         cancel_lru_locks mdc
18615
18616         cat /etc/hosts >> $tmp
18617         lctl set_param -n mdc.*.stats=clear
18618
18619         # append data to the same file it should update local page
18620         echo "Append to the same page"
18621         cat /etc/hosts >> $dom
18622         local num=$(get_mdc_stats $mdtidx ost_read)
18623         local ra=$(get_mdc_stats $mdtidx req_active)
18624         local rw=$(get_mdc_stats $mdtidx req_waittime)
18625
18626         [ -z $num ] || error "$num READ RPC occured"
18627         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18628         echo "... DONE"
18629
18630         # compare content
18631         cmp $tmp $dom || error "file miscompare"
18632
18633         cancel_lru_locks mdc
18634         lctl set_param -n mdc.*.stats=clear
18635
18636         echo "Open and read file"
18637         cat $dom > /dev/null
18638         local num=$(get_mdc_stats $mdtidx ost_read)
18639         local ra=$(get_mdc_stats $mdtidx req_active)
18640         local rw=$(get_mdc_stats $mdtidx req_waittime)
18641
18642         [ -z $num ] || error "$num READ RPC occured"
18643         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18644         echo "... DONE"
18645
18646         # compare content
18647         cmp $tmp $dom || error "file miscompare"
18648
18649         return 0
18650 }
18651 run_test 271d "DoM: read on open (1K file in reply buffer)"
18652
18653 test_271f() {
18654         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18655                 skip "Need MDS version at least 2.10.57"
18656
18657         local dom=$DIR/$tdir/dom
18658         local tmp=$TMP/$tfile
18659         trap "cleanup_271def_tests $tmp" EXIT
18660
18661         mkdir -p $DIR/$tdir
18662
18663         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18664
18665         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18666
18667         cancel_lru_locks mdc
18668         dd if=/dev/urandom of=$tmp bs=265000 count=1
18669         dd if=$tmp of=$dom bs=265000 count=1
18670         cancel_lru_locks mdc
18671         cat /etc/hosts >> $tmp
18672         lctl set_param -n mdc.*.stats=clear
18673
18674         echo "Append to the same page"
18675         cat /etc/hosts >> $dom
18676         local num=$(get_mdc_stats $mdtidx ost_read)
18677         local ra=$(get_mdc_stats $mdtidx req_active)
18678         local rw=$(get_mdc_stats $mdtidx req_waittime)
18679
18680         [ -z $num ] || error "$num READ RPC occured"
18681         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18682         echo "... DONE"
18683
18684         # compare content
18685         cmp $tmp $dom || error "file miscompare"
18686
18687         cancel_lru_locks mdc
18688         lctl set_param -n mdc.*.stats=clear
18689
18690         echo "Open and read file"
18691         cat $dom > /dev/null
18692         local num=$(get_mdc_stats $mdtidx ost_read)
18693         local ra=$(get_mdc_stats $mdtidx req_active)
18694         local rw=$(get_mdc_stats $mdtidx req_waittime)
18695
18696         [ -z $num ] && num=0
18697         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18698         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18699         echo "... DONE"
18700
18701         # compare content
18702         cmp $tmp $dom || error "file miscompare"
18703
18704         return 0
18705 }
18706 run_test 271f "DoM: read on open (200K file and read tail)"
18707
18708 test_271g() {
18709         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18710                 skip "Skipping due to old client or server version"
18711
18712         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18713         # to get layout
18714         $CHECKSTAT -t file $DIR1/$tfile
18715
18716         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18717         MULTIOP_PID=$!
18718         sleep 1
18719         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18720         $LCTL set_param fail_loc=0x80000314
18721         rm $DIR1/$tfile || error "Unlink fails"
18722         RC=$?
18723         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18724         [ $RC -eq 0 ] || error "Failed write to stale object"
18725 }
18726 run_test 271g "Discard DoM data vs client flush race"
18727
18728 test_272a() {
18729         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18730                 skip "Need MDS version at least 2.11.50"
18731
18732         local dom=$DIR/$tdir/dom
18733         mkdir -p $DIR/$tdir
18734
18735         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18736         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18737                 error "failed to write data into $dom"
18738         local old_md5=$(md5sum $dom)
18739
18740         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18741                 error "failed to migrate to the same DoM component"
18742
18743         local new_md5=$(md5sum $dom)
18744
18745         [ "$old_md5" == "$new_md5" ] ||
18746                 error "md5sum differ: $old_md5, $new_md5"
18747
18748         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18749                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18750 }
18751 run_test 272a "DoM migration: new layout with the same DOM component"
18752
18753 test_272b() {
18754         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18755                 skip "Need MDS version at least 2.11.50"
18756
18757         local dom=$DIR/$tdir/dom
18758         mkdir -p $DIR/$tdir
18759         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18760
18761         local mdtidx=$($LFS getstripe -m $dom)
18762         local mdtname=MDT$(printf %04x $mdtidx)
18763         local facet=mds$((mdtidx + 1))
18764
18765         local mdtfree1=$(do_facet $facet \
18766                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18767         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18768                 error "failed to write data into $dom"
18769         local old_md5=$(md5sum $dom)
18770         cancel_lru_locks mdc
18771         local mdtfree1=$(do_facet $facet \
18772                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18773
18774         $LFS migrate -c2 $dom ||
18775                 error "failed to migrate to the new composite layout"
18776         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18777                 error "MDT stripe was not removed"
18778
18779         cancel_lru_locks mdc
18780         local new_md5=$(md5sum $dom)
18781         [ "$old_md5" == "$new_md5" ] ||
18782                 error "$old_md5 != $new_md5"
18783
18784         # Skip free space checks with ZFS
18785         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18786                 local mdtfree2=$(do_facet $facet \
18787                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18788                 [ $mdtfree2 -gt $mdtfree1 ] ||
18789                         error "MDT space is not freed after migration"
18790         fi
18791         return 0
18792 }
18793 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18794
18795 test_272c() {
18796         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18797                 skip "Need MDS version at least 2.11.50"
18798
18799         local dom=$DIR/$tdir/$tfile
18800         mkdir -p $DIR/$tdir
18801         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18802
18803         local mdtidx=$($LFS getstripe -m $dom)
18804         local mdtname=MDT$(printf %04x $mdtidx)
18805         local facet=mds$((mdtidx + 1))
18806
18807         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18808                 error "failed to write data into $dom"
18809         local old_md5=$(md5sum $dom)
18810         cancel_lru_locks mdc
18811         local mdtfree1=$(do_facet $facet \
18812                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18813
18814         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18815                 error "failed to migrate to the new composite layout"
18816         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18817                 error "MDT stripe was not removed"
18818
18819         cancel_lru_locks mdc
18820         local new_md5=$(md5sum $dom)
18821         [ "$old_md5" == "$new_md5" ] ||
18822                 error "$old_md5 != $new_md5"
18823
18824         # Skip free space checks with ZFS
18825         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18826                 local mdtfree2=$(do_facet $facet \
18827                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18828                 [ $mdtfree2 -gt $mdtfree1 ] ||
18829                         error "MDS space is not freed after migration"
18830         fi
18831         return 0
18832 }
18833 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18834
18835 test_272d() {
18836         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18837                 skip "Need MDS version at least 2.12.55"
18838
18839         local dom=$DIR/$tdir/$tfile
18840         mkdir -p $DIR/$tdir
18841         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18842
18843         local mdtidx=$($LFS getstripe -m $dom)
18844         local mdtname=MDT$(printf %04x $mdtidx)
18845         local facet=mds$((mdtidx + 1))
18846
18847         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18848                 error "failed to write data into $dom"
18849         local old_md5=$(md5sum $dom)
18850         cancel_lru_locks mdc
18851         local mdtfree1=$(do_facet $facet \
18852                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18853
18854         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
18855                 error "failed mirroring to the new composite layout"
18856         $LFS mirror resync $dom ||
18857                 error "failed mirror resync"
18858         $LFS mirror split --mirror-id 1 -d $dom ||
18859                 error "failed mirror split"
18860
18861         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18862                 error "MDT stripe was not removed"
18863
18864         cancel_lru_locks mdc
18865         local new_md5=$(md5sum $dom)
18866         [ "$old_md5" == "$new_md5" ] ||
18867                 error "$old_md5 != $new_md5"
18868
18869         # Skip free space checks with ZFS
18870         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18871                 local mdtfree2=$(do_facet $facet \
18872                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18873                 [ $mdtfree2 -gt $mdtfree1 ] ||
18874                         error "MDS space is not freed after DOM mirror deletion"
18875         fi
18876         return 0
18877 }
18878 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
18879
18880 test_272e() {
18881         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18882                 skip "Need MDS version at least 2.12.55"
18883
18884         local dom=$DIR/$tdir/$tfile
18885         mkdir -p $DIR/$tdir
18886         $LFS setstripe -c 2 $dom
18887
18888         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
18889                 error "failed to write data into $dom"
18890         local old_md5=$(md5sum $dom)
18891         cancel_lru_locks mdc
18892
18893         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
18894                 error "failed mirroring to the DOM layout"
18895         $LFS mirror resync $dom ||
18896                 error "failed mirror resync"
18897         $LFS mirror split --mirror-id 1 -d $dom ||
18898                 error "failed mirror split"
18899
18900         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18901                 error "MDT stripe was not removed"
18902
18903         cancel_lru_locks mdc
18904         local new_md5=$(md5sum $dom)
18905         [ "$old_md5" == "$new_md5" ] ||
18906                 error "$old_md5 != $new_md5"
18907
18908         return 0
18909 }
18910 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
18911
18912 test_272f() {
18913         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18914                 skip "Need MDS version at least 2.12.55"
18915
18916         local dom=$DIR/$tdir/$tfile
18917         mkdir -p $DIR/$tdir
18918         $LFS setstripe -c 2 $dom
18919
18920         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
18921                 error "failed to write data into $dom"
18922         local old_md5=$(md5sum $dom)
18923         cancel_lru_locks mdc
18924
18925         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
18926                 error "failed migrating to the DOM file"
18927
18928         cancel_lru_locks mdc
18929         local new_md5=$(md5sum $dom)
18930         [ "$old_md5" != "$new_md5" ] &&
18931                 error "$old_md5 != $new_md5"
18932
18933         return 0
18934 }
18935 run_test 272f "DoM migration: OST-striped file to DOM file"
18936
18937 test_273a() {
18938         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18939                 skip "Need MDS version at least 2.11.50"
18940
18941         # Layout swap cannot be done if either file has DOM component,
18942         # this will never be supported, migration should be used instead
18943
18944         local dom=$DIR/$tdir/$tfile
18945         mkdir -p $DIR/$tdir
18946
18947         $LFS setstripe -c2 ${dom}_plain
18948         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
18949         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
18950                 error "can swap layout with DoM component"
18951         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
18952                 error "can swap layout with DoM component"
18953
18954         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
18955         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
18956                 error "can swap layout with DoM component"
18957         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
18958                 error "can swap layout with DoM component"
18959         return 0
18960 }
18961 run_test 273a "DoM: layout swapping should fail with DOM"
18962
18963 test_275() {
18964         remote_ost_nodsh && skip "remote OST with nodsh"
18965         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
18966                 skip "Need OST version >= 2.10.57"
18967
18968         local file=$DIR/$tfile
18969         local oss
18970
18971         oss=$(comma_list $(osts_nodes))
18972
18973         dd if=/dev/urandom of=$file bs=1M count=2 ||
18974                 error "failed to create a file"
18975         cancel_lru_locks osc
18976
18977         #lock 1
18978         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18979                 error "failed to read a file"
18980
18981 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
18982         $LCTL set_param fail_loc=0x8000031f
18983
18984         cancel_lru_locks osc &
18985         sleep 1
18986
18987 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
18988         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
18989         #IO takes another lock, but matches the PENDING one
18990         #and places it to the IO RPC
18991         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18992                 error "failed to read a file with PENDING lock"
18993 }
18994 run_test 275 "Read on a canceled duplicate lock"
18995
18996 test_276() {
18997         remote_ost_nodsh && skip "remote OST with nodsh"
18998         local pid
18999
19000         do_facet ost1 "(while true; do \
19001                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
19002                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
19003         pid=$!
19004
19005         for LOOP in $(seq 20); do
19006                 stop ost1
19007                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
19008         done
19009         kill -9 $pid
19010         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
19011                 rm $TMP/sanity_276_pid"
19012 }
19013 run_test 276 "Race between mount and obd_statfs"
19014
19015 test_277() {
19016         $LCTL set_param ldlm.namespaces.*.lru_size=0
19017         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
19018         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19019                         grep ^used_mb | awk '{print $2}')
19020         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
19021         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
19022                 oflag=direct conv=notrunc
19023         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19024                         grep ^used_mb | awk '{print $2}')
19025         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
19026 }
19027 run_test 277 "Direct IO shall drop page cache"
19028
19029 test_278() {
19030         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19031         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19032         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
19033                 skip "needs the same host for mdt1 mdt2" && return
19034
19035         local pid1
19036         local pid2
19037
19038 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
19039         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
19040         stop mds2 &
19041         pid2=$!
19042
19043         stop mds1
19044
19045         echo "Starting MDTs"
19046         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
19047         wait $pid2
19048 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
19049 #will return NULL
19050         do_facet mds2 $LCTL set_param fail_loc=0
19051
19052         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
19053         wait_recovery_complete mds2
19054 }
19055 run_test 278 "Race starting MDS between MDTs stop/start"
19056
19057 cleanup_test_300() {
19058         trap 0
19059         umask $SAVE_UMASK
19060 }
19061 test_striped_dir() {
19062         local mdt_index=$1
19063         local stripe_count
19064         local stripe_index
19065
19066         mkdir -p $DIR/$tdir
19067
19068         SAVE_UMASK=$(umask)
19069         trap cleanup_test_300 RETURN EXIT
19070
19071         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
19072                                                 $DIR/$tdir/striped_dir ||
19073                 error "set striped dir error"
19074
19075         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
19076         [ "$mode" = "755" ] || error "expect 755 got $mode"
19077
19078         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
19079                 error "getdirstripe failed"
19080         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
19081         if [ "$stripe_count" != "2" ]; then
19082                 error "1:stripe_count is $stripe_count, expect 2"
19083         fi
19084         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
19085         if [ "$stripe_count" != "2" ]; then
19086                 error "2:stripe_count is $stripe_count, expect 2"
19087         fi
19088
19089         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
19090         if [ "$stripe_index" != "$mdt_index" ]; then
19091                 error "stripe_index is $stripe_index, expect $mdt_index"
19092         fi
19093
19094         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19095                 error "nlink error after create striped dir"
19096
19097         mkdir $DIR/$tdir/striped_dir/a
19098         mkdir $DIR/$tdir/striped_dir/b
19099
19100         stat $DIR/$tdir/striped_dir/a ||
19101                 error "create dir under striped dir failed"
19102         stat $DIR/$tdir/striped_dir/b ||
19103                 error "create dir under striped dir failed"
19104
19105         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
19106                 error "nlink error after mkdir"
19107
19108         rmdir $DIR/$tdir/striped_dir/a
19109         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
19110                 error "nlink error after rmdir"
19111
19112         rmdir $DIR/$tdir/striped_dir/b
19113         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19114                 error "nlink error after rmdir"
19115
19116         chattr +i $DIR/$tdir/striped_dir
19117         createmany -o $DIR/$tdir/striped_dir/f 10 &&
19118                 error "immutable flags not working under striped dir!"
19119         chattr -i $DIR/$tdir/striped_dir
19120
19121         rmdir $DIR/$tdir/striped_dir ||
19122                 error "rmdir striped dir error"
19123
19124         cleanup_test_300
19125
19126         true
19127 }
19128
19129 test_300a() {
19130         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19131                 skip "skipped for lustre < 2.7.0"
19132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19133         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19134
19135         test_striped_dir 0 || error "failed on striped dir on MDT0"
19136         test_striped_dir 1 || error "failed on striped dir on MDT0"
19137 }
19138 run_test 300a "basic striped dir sanity test"
19139
19140 test_300b() {
19141         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19142                 skip "skipped for lustre < 2.7.0"
19143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19144         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19145
19146         local i
19147         local mtime1
19148         local mtime2
19149         local mtime3
19150
19151         test_mkdir $DIR/$tdir || error "mkdir fail"
19152         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19153                 error "set striped dir error"
19154         for i in {0..9}; do
19155                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
19156                 sleep 1
19157                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
19158                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
19159                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
19160                 sleep 1
19161                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
19162                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
19163                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
19164         done
19165         true
19166 }
19167 run_test 300b "check ctime/mtime for striped dir"
19168
19169 test_300c() {
19170         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19171                 skip "skipped for lustre < 2.7.0"
19172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19173         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19174
19175         local file_count
19176
19177         mkdir -p $DIR/$tdir
19178         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
19179                 error "set striped dir error"
19180
19181         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
19182                 error "chown striped dir failed"
19183
19184         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
19185                 error "create 5k files failed"
19186
19187         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
19188
19189         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
19190
19191         rm -rf $DIR/$tdir
19192 }
19193 run_test 300c "chown && check ls under striped directory"
19194
19195 test_300d() {
19196         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19197                 skip "skipped for lustre < 2.7.0"
19198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19199         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19200
19201         local stripe_count
19202         local file
19203
19204         mkdir -p $DIR/$tdir
19205         $LFS setstripe -c 2 $DIR/$tdir
19206
19207         #local striped directory
19208         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19209                 error "set striped dir error"
19210         createmany -o $DIR/$tdir/striped_dir/f 10 ||
19211                 error "create 10 files failed"
19212
19213         #remote striped directory
19214         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
19215                 error "set striped dir error"
19216         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
19217                 error "create 10 files failed"
19218
19219         for file in $(find $DIR/$tdir); do
19220                 stripe_count=$($LFS getstripe -c $file)
19221                 [ $stripe_count -eq 2 ] ||
19222                         error "wrong stripe $stripe_count for $file"
19223         done
19224
19225         rm -rf $DIR/$tdir
19226 }
19227 run_test 300d "check default stripe under striped directory"
19228
19229 test_300e() {
19230         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19231                 skip "Need MDS version at least 2.7.55"
19232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19233         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19234
19235         local stripe_count
19236         local file
19237
19238         mkdir -p $DIR/$tdir
19239
19240         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19241                 error "set striped dir error"
19242
19243         touch $DIR/$tdir/striped_dir/a
19244         touch $DIR/$tdir/striped_dir/b
19245         touch $DIR/$tdir/striped_dir/c
19246
19247         mkdir $DIR/$tdir/striped_dir/dir_a
19248         mkdir $DIR/$tdir/striped_dir/dir_b
19249         mkdir $DIR/$tdir/striped_dir/dir_c
19250
19251         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
19252                 error "set striped adir under striped dir error"
19253
19254         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
19255                 error "set striped bdir under striped dir error"
19256
19257         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
19258                 error "set striped cdir under striped dir error"
19259
19260         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
19261                 error "rename dir under striped dir fails"
19262
19263         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
19264                 error "rename dir under different stripes fails"
19265
19266         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
19267                 error "rename file under striped dir should succeed"
19268
19269         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
19270                 error "rename dir under striped dir should succeed"
19271
19272         rm -rf $DIR/$tdir
19273 }
19274 run_test 300e "check rename under striped directory"
19275
19276 test_300f() {
19277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19278         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19279         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19280                 skip "Need MDS version at least 2.7.55"
19281
19282         local stripe_count
19283         local file
19284
19285         rm -rf $DIR/$tdir
19286         mkdir -p $DIR/$tdir
19287
19288         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19289                 error "set striped dir error"
19290
19291         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
19292                 error "set striped dir error"
19293
19294         touch $DIR/$tdir/striped_dir/a
19295         mkdir $DIR/$tdir/striped_dir/dir_a
19296         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
19297                 error "create striped dir under striped dir fails"
19298
19299         touch $DIR/$tdir/striped_dir1/b
19300         mkdir $DIR/$tdir/striped_dir1/dir_b
19301         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
19302                 error "create striped dir under striped dir fails"
19303
19304         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
19305                 error "rename dir under different striped dir should fail"
19306
19307         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
19308                 error "rename striped dir under diff striped dir should fail"
19309
19310         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
19311                 error "rename file under diff striped dirs fails"
19312
19313         rm -rf $DIR/$tdir
19314 }
19315 run_test 300f "check rename cross striped directory"
19316
19317 test_300_check_default_striped_dir()
19318 {
19319         local dirname=$1
19320         local default_count=$2
19321         local default_index=$3
19322         local stripe_count
19323         local stripe_index
19324         local dir_stripe_index
19325         local dir
19326
19327         echo "checking $dirname $default_count $default_index"
19328         $LFS setdirstripe -D -c $default_count -i $default_index \
19329                                 -t all_char $DIR/$tdir/$dirname ||
19330                 error "set default stripe on striped dir error"
19331         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
19332         [ $stripe_count -eq $default_count ] ||
19333                 error "expect $default_count get $stripe_count for $dirname"
19334
19335         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
19336         [ $stripe_index -eq $default_index ] ||
19337                 error "expect $default_index get $stripe_index for $dirname"
19338
19339         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
19340                                                 error "create dirs failed"
19341
19342         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
19343         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
19344         for dir in $(find $DIR/$tdir/$dirname/*); do
19345                 stripe_count=$($LFS getdirstripe -c $dir)
19346                 [ $stripe_count -eq $default_count ] ||
19347                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
19348                 error "stripe count $default_count != $stripe_count for $dir"
19349
19350                 stripe_index=$($LFS getdirstripe -i $dir)
19351                 [ $default_index -eq -1 ] ||
19352                         [ $stripe_index -eq $default_index ] ||
19353                         error "$stripe_index != $default_index for $dir"
19354
19355                 #check default stripe
19356                 stripe_count=$($LFS getdirstripe -D -c $dir)
19357                 [ $stripe_count -eq $default_count ] ||
19358                 error "default count $default_count != $stripe_count for $dir"
19359
19360                 stripe_index=$($LFS getdirstripe -D -i $dir)
19361                 [ $stripe_index -eq $default_index ] ||
19362                 error "default index $default_index != $stripe_index for $dir"
19363         done
19364         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
19365 }
19366
19367 test_300g() {
19368         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19369         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19370                 skip "Need MDS version at least 2.7.55"
19371
19372         local dir
19373         local stripe_count
19374         local stripe_index
19375
19376         mkdir $DIR/$tdir
19377         mkdir $DIR/$tdir/normal_dir
19378
19379         #Checking when client cache stripe index
19380         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
19381         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
19382                 error "create striped_dir failed"
19383
19384         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
19385                 error "create dir0 fails"
19386         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
19387         [ $stripe_index -eq 0 ] ||
19388                 error "dir0 expect index 0 got $stripe_index"
19389
19390         mkdir $DIR/$tdir/striped_dir/dir1 ||
19391                 error "create dir1 fails"
19392         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
19393         [ $stripe_index -eq 1 ] ||
19394                 error "dir1 expect index 1 got $stripe_index"
19395
19396         #check default stripe count/stripe index
19397         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
19398         test_300_check_default_striped_dir normal_dir 1 0
19399         test_300_check_default_striped_dir normal_dir 2 1
19400         test_300_check_default_striped_dir normal_dir 2 -1
19401
19402         #delete default stripe information
19403         echo "delete default stripeEA"
19404         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
19405                 error "set default stripe on striped dir error"
19406
19407         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
19408         for dir in $(find $DIR/$tdir/normal_dir/*); do
19409                 stripe_count=$($LFS getdirstripe -c $dir)
19410                 [ $stripe_count -eq 0 ] ||
19411                         error "expect 1 get $stripe_count for $dir"
19412                 stripe_index=$($LFS getdirstripe -i $dir)
19413                 [ $stripe_index -eq 0 ] ||
19414                         error "expect 0 get $stripe_index for $dir"
19415         done
19416 }
19417 run_test 300g "check default striped directory for normal directory"
19418
19419 test_300h() {
19420         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19421         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19422                 skip "Need MDS version at least 2.7.55"
19423
19424         local dir
19425         local stripe_count
19426
19427         mkdir $DIR/$tdir
19428         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19429                 error "set striped dir error"
19430
19431         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
19432         test_300_check_default_striped_dir striped_dir 1 0
19433         test_300_check_default_striped_dir striped_dir 2 1
19434         test_300_check_default_striped_dir striped_dir 2 -1
19435
19436         #delete default stripe information
19437         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
19438                 error "set default stripe on striped dir error"
19439
19440         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
19441         for dir in $(find $DIR/$tdir/striped_dir/*); do
19442                 stripe_count=$($LFS getdirstripe -c $dir)
19443                 [ $stripe_count -eq 0 ] ||
19444                         error "expect 1 get $stripe_count for $dir"
19445         done
19446 }
19447 run_test 300h "check default striped directory for striped directory"
19448
19449 test_300i() {
19450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19451         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19452         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19453                 skip "Need MDS version at least 2.7.55"
19454
19455         local stripe_count
19456         local file
19457
19458         mkdir $DIR/$tdir
19459
19460         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19461                 error "set striped dir error"
19462
19463         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19464                 error "create files under striped dir failed"
19465
19466         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
19467                 error "set striped hashdir error"
19468
19469         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
19470                 error "create dir0 under hash dir failed"
19471         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
19472                 error "create dir1 under hash dir failed"
19473
19474         # unfortunately, we need to umount to clear dir layout cache for now
19475         # once we fully implement dir layout, we can drop this
19476         umount_client $MOUNT || error "umount failed"
19477         mount_client $MOUNT || error "mount failed"
19478
19479         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
19480         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
19481         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
19482
19483         #set the stripe to be unknown hash type
19484         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
19485         $LCTL set_param fail_loc=0x1901
19486         for ((i = 0; i < 10; i++)); do
19487                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
19488                         error "stat f-$i failed"
19489                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
19490         done
19491
19492         touch $DIR/$tdir/striped_dir/f0 &&
19493                 error "create under striped dir with unknown hash should fail"
19494
19495         $LCTL set_param fail_loc=0
19496
19497         umount_client $MOUNT || error "umount failed"
19498         mount_client $MOUNT || error "mount failed"
19499
19500         return 0
19501 }
19502 run_test 300i "client handle unknown hash type striped directory"
19503
19504 test_300j() {
19505         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19507         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19508                 skip "Need MDS version at least 2.7.55"
19509
19510         local stripe_count
19511         local file
19512
19513         mkdir $DIR/$tdir
19514
19515         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
19516         $LCTL set_param fail_loc=0x1702
19517         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19518                 error "set striped dir error"
19519
19520         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19521                 error "create files under striped dir failed"
19522
19523         $LCTL set_param fail_loc=0
19524
19525         rm -rf $DIR/$tdir || error "unlink striped dir fails"
19526
19527         return 0
19528 }
19529 run_test 300j "test large update record"
19530
19531 test_300k() {
19532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19533         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19534         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19535                 skip "Need MDS version at least 2.7.55"
19536
19537         # this test needs a huge transaction
19538         local kb
19539         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
19540         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
19541
19542         local stripe_count
19543         local file
19544
19545         mkdir $DIR/$tdir
19546
19547         #define OBD_FAIL_LARGE_STRIPE   0x1703
19548         $LCTL set_param fail_loc=0x1703
19549         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
19550                 error "set striped dir error"
19551         $LCTL set_param fail_loc=0
19552
19553         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19554                 error "getstripeddir fails"
19555         rm -rf $DIR/$tdir/striped_dir ||
19556                 error "unlink striped dir fails"
19557
19558         return 0
19559 }
19560 run_test 300k "test large striped directory"
19561
19562 test_300l() {
19563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19564         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19565         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19566                 skip "Need MDS version at least 2.7.55"
19567
19568         local stripe_index
19569
19570         test_mkdir -p $DIR/$tdir/striped_dir
19571         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
19572                         error "chown $RUNAS_ID failed"
19573         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
19574                 error "set default striped dir failed"
19575
19576         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
19577         $LCTL set_param fail_loc=0x80000158
19578         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
19579
19580         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
19581         [ $stripe_index -eq 1 ] ||
19582                 error "expect 1 get $stripe_index for $dir"
19583 }
19584 run_test 300l "non-root user to create dir under striped dir with stale layout"
19585
19586 test_300m() {
19587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19588         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
19589         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19590                 skip "Need MDS version at least 2.7.55"
19591
19592         mkdir -p $DIR/$tdir/striped_dir
19593         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
19594                 error "set default stripes dir error"
19595
19596         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
19597
19598         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
19599         [ $stripe_count -eq 0 ] ||
19600                         error "expect 0 get $stripe_count for a"
19601
19602         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
19603                 error "set default stripes dir error"
19604
19605         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
19606
19607         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
19608         [ $stripe_count -eq 0 ] ||
19609                         error "expect 0 get $stripe_count for b"
19610
19611         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
19612                 error "set default stripes dir error"
19613
19614         mkdir $DIR/$tdir/striped_dir/c &&
19615                 error "default stripe_index is invalid, mkdir c should fails"
19616
19617         rm -rf $DIR/$tdir || error "rmdir fails"
19618 }
19619 run_test 300m "setstriped directory on single MDT FS"
19620
19621 cleanup_300n() {
19622         local list=$(comma_list $(mdts_nodes))
19623
19624         trap 0
19625         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19626 }
19627
19628 test_300n() {
19629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19630         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19631         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19632                 skip "Need MDS version at least 2.7.55"
19633         remote_mds_nodsh && skip "remote MDS with nodsh"
19634
19635         local stripe_index
19636         local list=$(comma_list $(mdts_nodes))
19637
19638         trap cleanup_300n RETURN EXIT
19639         mkdir -p $DIR/$tdir
19640         chmod 777 $DIR/$tdir
19641         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
19642                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19643                 error "create striped dir succeeds with gid=0"
19644
19645         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19646         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
19647                 error "create striped dir fails with gid=-1"
19648
19649         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19650         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
19651                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19652                 error "set default striped dir succeeds with gid=0"
19653
19654
19655         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19656         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
19657                 error "set default striped dir fails with gid=-1"
19658
19659
19660         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19661         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
19662                                         error "create test_dir fails"
19663         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
19664                                         error "create test_dir1 fails"
19665         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
19666                                         error "create test_dir2 fails"
19667         cleanup_300n
19668 }
19669 run_test 300n "non-root user to create dir under striped dir with default EA"
19670
19671 test_300o() {
19672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19673         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19674         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19675                 skip "Need MDS version at least 2.7.55"
19676
19677         local numfree1
19678         local numfree2
19679
19680         mkdir -p $DIR/$tdir
19681
19682         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
19683         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
19684         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
19685                 skip "not enough free inodes $numfree1 $numfree2"
19686         fi
19687
19688         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
19689         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
19690         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
19691                 skip "not enough free space $numfree1 $numfree2"
19692         fi
19693
19694         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
19695                 error "setdirstripe fails"
19696
19697         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
19698                 error "create dirs fails"
19699
19700         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
19701         ls $DIR/$tdir/striped_dir > /dev/null ||
19702                 error "ls striped dir fails"
19703         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
19704                 error "unlink big striped dir fails"
19705 }
19706 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
19707
19708 test_300p() {
19709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19710         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19711         remote_mds_nodsh && skip "remote MDS with nodsh"
19712
19713         mkdir -p $DIR/$tdir
19714
19715         #define OBD_FAIL_OUT_ENOSPC     0x1704
19716         do_facet mds2 lctl set_param fail_loc=0x80001704
19717         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
19718                  && error "create striped directory should fail"
19719
19720         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
19721
19722         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
19723         true
19724 }
19725 run_test 300p "create striped directory without space"
19726
19727 test_300q() {
19728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19729         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19730
19731         local fd=$(free_fd)
19732         local cmd="exec $fd<$tdir"
19733         cd $DIR
19734         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
19735         eval $cmd
19736         cmd="exec $fd<&-"
19737         trap "eval $cmd" EXIT
19738         cd $tdir || error "cd $tdir fails"
19739         rmdir  ../$tdir || error "rmdir $tdir fails"
19740         mkdir local_dir && error "create dir succeeds"
19741         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
19742         eval $cmd
19743         return 0
19744 }
19745 run_test 300q "create remote directory under orphan directory"
19746
19747 test_300r() {
19748         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
19749                 skip "Need MDS version at least 2.7.55" && return
19750         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19751
19752         mkdir $DIR/$tdir
19753
19754         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19755                 error "set striped dir error"
19756
19757         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19758                 error "getstripeddir fails"
19759
19760         local stripe_count
19761         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19762                       awk '/lmv_stripe_count:/ { print $2 }')
19763
19764         [ $MDSCOUNT -ne $stripe_count ] &&
19765                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19766
19767         rm -rf $DIR/$tdir/striped_dir ||
19768                 error "unlink striped dir fails"
19769 }
19770 run_test 300r "test -1 striped directory"
19771
19772 prepare_remote_file() {
19773         mkdir $DIR/$tdir/src_dir ||
19774                 error "create remote source failed"
19775
19776         cp /etc/hosts $DIR/$tdir/src_dir/a ||
19777                  error "cp to remote source failed"
19778         touch $DIR/$tdir/src_dir/a
19779
19780         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
19781                 error "create remote target dir failed"
19782
19783         touch $DIR/$tdir/tgt_dir/b
19784
19785         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
19786                 error "rename dir cross MDT failed!"
19787
19788         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
19789                 error "src_child still exists after rename"
19790
19791         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
19792                 error "missing file(a) after rename"
19793
19794         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
19795                 error "diff after rename"
19796 }
19797
19798 test_310a() {
19799         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19801
19802         local remote_file=$DIR/$tdir/tgt_dir/b
19803
19804         mkdir -p $DIR/$tdir
19805
19806         prepare_remote_file || error "prepare remote file failed"
19807
19808         #open-unlink file
19809         $OPENUNLINK $remote_file $remote_file ||
19810                 error "openunlink $remote_file failed"
19811         $CHECKSTAT -a $remote_file || error "$remote_file exists"
19812 }
19813 run_test 310a "open unlink remote file"
19814
19815 test_310b() {
19816         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19818
19819         local remote_file=$DIR/$tdir/tgt_dir/b
19820
19821         mkdir -p $DIR/$tdir
19822
19823         prepare_remote_file || error "prepare remote file failed"
19824
19825         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19826         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19827         $CHECKSTAT -t file $remote_file || error "check file failed"
19828 }
19829 run_test 310b "unlink remote file with multiple links while open"
19830
19831 test_310c() {
19832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19833         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19834
19835         local remote_file=$DIR/$tdir/tgt_dir/b
19836
19837         mkdir -p $DIR/$tdir
19838
19839         prepare_remote_file || error "prepare remote file failed"
19840
19841         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19842         multiop_bg_pause $remote_file O_uc ||
19843                         error "mulitop failed for remote file"
19844         MULTIPID=$!
19845         $MULTIOP $DIR/$tfile Ouc
19846         kill -USR1 $MULTIPID
19847         wait $MULTIPID
19848 }
19849 run_test 310c "open-unlink remote file with multiple links"
19850
19851 #LU-4825
19852 test_311() {
19853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19854         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19855         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
19856                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
19857         remote_mds_nodsh && skip "remote MDS with nodsh"
19858
19859         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19860         local mdts=$(comma_list $(mdts_nodes))
19861
19862         mkdir -p $DIR/$tdir
19863         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19864         createmany -o $DIR/$tdir/$tfile. 1000
19865
19866         # statfs data is not real time, let's just calculate it
19867         old_iused=$((old_iused + 1000))
19868
19869         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19870                         osp.*OST0000*MDT0000.create_count")
19871         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19872                                 osp.*OST0000*MDT0000.max_create_count")
19873         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
19874
19875         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
19876         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
19877         [ $index -ne 0 ] || error "$tfile stripe index is 0"
19878
19879         unlinkmany $DIR/$tdir/$tfile. 1000
19880
19881         do_nodes $mdts "$LCTL set_param -n \
19882                         osp.*OST0000*.max_create_count=$max_count"
19883         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
19884                 do_nodes $mdts "$LCTL set_param -n \
19885                                 osp.*OST0000*.create_count=$count"
19886         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
19887                         grep "=0" && error "create_count is zero"
19888
19889         local new_iused
19890         for i in $(seq 120); do
19891                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19892                 # system may be too busy to destroy all objs in time, use
19893                 # a somewhat small value to not fail autotest
19894                 [ $((old_iused - new_iused)) -gt 400 ] && break
19895                 sleep 1
19896         done
19897
19898         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
19899         [ $((old_iused - new_iused)) -gt 400 ] ||
19900                 error "objs not destroyed after unlink"
19901 }
19902 run_test 311 "disable OSP precreate, and unlink should destroy objs"
19903
19904 zfs_oid_to_objid()
19905 {
19906         local ost=$1
19907         local objid=$2
19908
19909         local vdevdir=$(dirname $(facet_vdevice $ost))
19910         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
19911         local zfs_zapid=$(do_facet $ost $cmd |
19912                           grep -w "/O/0/d$((objid%32))" -C 5 |
19913                           awk '/Object/{getline; print $1}')
19914         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
19915                           awk "/$objid = /"'{printf $3}')
19916
19917         echo $zfs_objid
19918 }
19919
19920 zfs_object_blksz() {
19921         local ost=$1
19922         local objid=$2
19923
19924         local vdevdir=$(dirname $(facet_vdevice $ost))
19925         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
19926         local blksz=$(do_facet $ost $cmd $objid |
19927                       awk '/dblk/{getline; printf $4}')
19928
19929         case "${blksz: -1}" in
19930                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
19931                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
19932                 *) ;;
19933         esac
19934
19935         echo $blksz
19936 }
19937
19938 test_312() { # LU-4856
19939         remote_ost_nodsh && skip "remote OST with nodsh"
19940         [ "$ost1_FSTYPE" = "zfs" ] ||
19941                 skip_env "the test only applies to zfs"
19942
19943         local max_blksz=$(do_facet ost1 \
19944                           $ZFS get -p recordsize $(facet_device ost1) |
19945                           awk '!/VALUE/{print $3}')
19946
19947         # to make life a little bit easier
19948         $LFS mkdir -c 1 -i 0 $DIR/$tdir
19949         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19950
19951         local tf=$DIR/$tdir/$tfile
19952         touch $tf
19953         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19954
19955         # Get ZFS object id
19956         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19957         # block size change by sequential overwrite
19958         local bs
19959
19960         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
19961                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
19962
19963                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
19964                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
19965         done
19966         rm -f $tf
19967
19968         # block size change by sequential append write
19969         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
19970         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19971         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19972         local count
19973
19974         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
19975                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
19976                         oflag=sync conv=notrunc
19977
19978                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
19979                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
19980                         error "blksz error, actual $blksz, " \
19981                                 "expected: 2 * $count * $PAGE_SIZE"
19982         done
19983         rm -f $tf
19984
19985         # random write
19986         touch $tf
19987         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19988         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19989
19990         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
19991         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19992         [ $blksz -eq $PAGE_SIZE ] ||
19993                 error "blksz error: $blksz, expected: $PAGE_SIZE"
19994
19995         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
19996         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19997         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
19998
19999         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
20000         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20001         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
20002 }
20003 run_test 312 "make sure ZFS adjusts its block size by write pattern"
20004
20005 test_313() {
20006         remote_ost_nodsh && skip "remote OST with nodsh"
20007
20008         local file=$DIR/$tfile
20009
20010         rm -f $file
20011         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
20012
20013         # define OBD_FAIL_TGT_RCVD_EIO           0x720
20014         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20015         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
20016                 error "write should failed"
20017         do_facet ost1 "$LCTL set_param fail_loc=0"
20018         rm -f $file
20019 }
20020 run_test 313 "io should fail after last_rcvd update fail"
20021
20022 test_314() {
20023         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20024
20025         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
20026         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20027         rm -f $DIR/$tfile
20028         wait_delete_completed
20029         do_facet ost1 "$LCTL set_param fail_loc=0"
20030 }
20031 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
20032
20033 test_315() { # LU-618
20034         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
20035
20036         local file=$DIR/$tfile
20037         rm -f $file
20038
20039         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
20040                 error "multiop file write failed"
20041         $MULTIOP $file oO_RDONLY:r4063232_c &
20042         PID=$!
20043
20044         sleep 2
20045
20046         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
20047         kill -USR1 $PID
20048
20049         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
20050         rm -f $file
20051 }
20052 run_test 315 "read should be accounted"
20053
20054 test_316() {
20055         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20056         large_xattr_enabled || skip_env "ea_inode feature disabled"
20057
20058         rm -rf $DIR/$tdir/d
20059         mkdir -p $DIR/$tdir/d
20060         chown nobody $DIR/$tdir/d
20061         touch $DIR/$tdir/d/file
20062
20063         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
20064 }
20065 run_test 316 "lfs mv"
20066
20067 test_317() {
20068         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
20069                 skip "Need MDS version at least 2.11.53"
20070         if [ "$ost1_FSTYPE" == "zfs" ]; then
20071                 skip "LU-10370: no implementation for ZFS"
20072         fi
20073
20074         local trunc_sz
20075         local grant_blk_size
20076
20077         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
20078                         awk '/grant_block_size:/ { print $2; exit; }')
20079         #
20080         # Create File of size 5M. Truncate it to below size's and verify
20081         # blocks count.
20082         #
20083         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
20084                 error "Create file $DIR/$tfile failed"
20085         stack_trap "rm -f $DIR/$tfile" EXIT
20086
20087         for trunc_sz in 2097152 4097 4000 509 0; do
20088                 $TRUNCATE $DIR/$tfile $trunc_sz ||
20089                         error "truncate $tfile to $trunc_sz failed"
20090                 local sz=$(stat --format=%s $DIR/$tfile)
20091                 local blk=$(stat --format=%b $DIR/$tfile)
20092                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
20093                                      grant_blk_size) * 8))
20094
20095                 if [[ $blk -ne $trunc_blk ]]; then
20096                         $(which stat) $DIR/$tfile
20097                         error "Expected Block $trunc_blk got $blk for $tfile"
20098                 fi
20099
20100                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20101                         error "Expected Size $trunc_sz got $sz for $tfile"
20102         done
20103
20104         #
20105         # sparse file test
20106         # Create file with a hole and write actual two blocks. Block count
20107         # must be 16.
20108         #
20109         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
20110                 conv=fsync || error "Create file : $DIR/$tfile"
20111
20112         # Calculate the final truncate size.
20113         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
20114
20115         #
20116         # truncate to size $trunc_sz bytes. Strip the last block
20117         # The block count must drop to 8
20118         #
20119         $TRUNCATE $DIR/$tfile $trunc_sz ||
20120                 error "truncate $tfile to $trunc_sz failed"
20121
20122         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
20123         sz=$(stat --format=%s $DIR/$tfile)
20124         blk=$(stat --format=%b $DIR/$tfile)
20125
20126         if [[ $blk -ne $trunc_bsz ]]; then
20127                 $(which stat) $DIR/$tfile
20128                 error "Expected Block $trunc_bsz got $blk for $tfile"
20129         fi
20130
20131         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20132                 error "Expected Size $trunc_sz got $sz for $tfile"
20133 }
20134 run_test 317 "Verify blocks get correctly update after truncate"
20135
20136 test_318() {
20137         local old_max_active=$($LCTL get_param -n \
20138                             llite.*.max_read_ahead_async_active 2>/dev/null)
20139
20140         $LCTL set_param llite.*.max_read_ahead_async_active=256
20141         local max_active=$($LCTL get_param -n \
20142                            llite.*.max_read_ahead_async_active 2>/dev/null)
20143         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
20144
20145         # currently reset to 0 is unsupported, leave it 512 for now.
20146         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
20147                 error "set max_read_ahead_async_active should fail"
20148
20149         $LCTL set_param llite.*.max_read_ahead_async_active=512
20150         max_active=$($LCTL get_param -n \
20151                      llite.*.max_read_ahead_async_active 2>/dev/null)
20152         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
20153
20154         # restore @max_active
20155         [ $old_max_active -ne 0 ] && $LCTL set_param \
20156                 llite.*.max_read_ahead_async_active=$old_max_active
20157
20158         local old_threshold=$($LCTL get_param -n \
20159                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20160         local max_per_file_mb=$($LCTL get_param -n \
20161                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
20162
20163         local invalid=$(($max_per_file_mb + 1))
20164         $LCTL set_param \
20165                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
20166                         && error "set $invalid should fail"
20167
20168         local valid=$(($invalid - 1))
20169         $LCTL set_param \
20170                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
20171                         error "set $valid should succeed"
20172         local threshold=$($LCTL get_param -n \
20173                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20174         [ $threshold -eq $valid ] || error \
20175                 "expect threshold $valid got $threshold"
20176         $LCTL set_param \
20177                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
20178 }
20179 run_test 318 "Verify async readahead tunables"
20180
20181 test_319() {
20182         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
20183
20184         local before=$(date +%s)
20185         local evict
20186         local mdir=$DIR/$tdir
20187         local file=$mdir/xxx
20188
20189         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
20190         touch $file
20191
20192 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
20193         $LCTL set_param fail_val=5 fail_loc=0x8000032c
20194         $LFS mv -m1 $file &
20195
20196         sleep 1
20197         dd if=$file of=/dev/null
20198         wait
20199         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
20200           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
20201
20202         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
20203 }
20204 run_test 319 "lost lease lock on migrate error"
20205
20206 test_fake_rw() {
20207         local read_write=$1
20208         if [ "$read_write" = "write" ]; then
20209                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
20210         elif [ "$read_write" = "read" ]; then
20211                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
20212         else
20213                 error "argument error"
20214         fi
20215
20216         # turn off debug for performance testing
20217         local saved_debug=$($LCTL get_param -n debug)
20218         $LCTL set_param debug=0
20219
20220         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20221
20222         # get ost1 size - lustre-OST0000
20223         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
20224         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
20225         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
20226
20227         if [ "$read_write" = "read" ]; then
20228                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
20229         fi
20230
20231         local start_time=$(date +%s.%N)
20232         $dd_cmd bs=1M count=$blocks oflag=sync ||
20233                 error "real dd $read_write error"
20234         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
20235
20236         if [ "$read_write" = "write" ]; then
20237                 rm -f $DIR/$tfile
20238         fi
20239
20240         # define OBD_FAIL_OST_FAKE_RW           0x238
20241         do_facet ost1 $LCTL set_param fail_loc=0x238
20242
20243         local start_time=$(date +%s.%N)
20244         $dd_cmd bs=1M count=$blocks oflag=sync ||
20245                 error "fake dd $read_write error"
20246         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
20247
20248         if [ "$read_write" = "write" ]; then
20249                 # verify file size
20250                 cancel_lru_locks osc
20251                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
20252                         error "$tfile size not $blocks MB"
20253         fi
20254         do_facet ost1 $LCTL set_param fail_loc=0
20255
20256         echo "fake $read_write $duration_fake vs. normal $read_write" \
20257                 "$duration in seconds"
20258         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
20259                 error_not_in_vm "fake write is slower"
20260
20261         $LCTL set_param -n debug="$saved_debug"
20262         rm -f $DIR/$tfile
20263 }
20264 test_399a() { # LU-7655 for OST fake write
20265         remote_ost_nodsh && skip "remote OST with nodsh"
20266
20267         test_fake_rw write
20268 }
20269 run_test 399a "fake write should not be slower than normal write"
20270
20271 test_399b() { # LU-8726 for OST fake read
20272         remote_ost_nodsh && skip "remote OST with nodsh"
20273         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
20274                 skip_env "ldiskfs only test"
20275         fi
20276
20277         test_fake_rw read
20278 }
20279 run_test 399b "fake read should not be slower than normal read"
20280
20281 test_400a() { # LU-1606, was conf-sanity test_74
20282         if ! which $CC > /dev/null 2>&1; then
20283                 skip_env "$CC is not installed"
20284         fi
20285
20286         local extra_flags=''
20287         local out=$TMP/$tfile
20288         local prefix=/usr/include/lustre
20289         local prog
20290
20291         if ! [[ -d $prefix ]]; then
20292                 # Assume we're running in tree and fixup the include path.
20293                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
20294                 extra_flags+=" -L$LUSTRE/utils/.lib"
20295         fi
20296
20297         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
20298                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
20299                         error "client api broken"
20300         done
20301         rm -f $out
20302 }
20303 run_test 400a "Lustre client api program can compile and link"
20304
20305 test_400b() { # LU-1606, LU-5011
20306         local header
20307         local out=$TMP/$tfile
20308         local prefix=/usr/include/linux/lustre
20309
20310         # We use a hard coded prefix so that this test will not fail
20311         # when run in tree. There are headers in lustre/include/lustre/
20312         # that are not packaged (like lustre_idl.h) and have more
20313         # complicated include dependencies (like config.h and lnet/types.h).
20314         # Since this test about correct packaging we just skip them when
20315         # they don't exist (see below) rather than try to fixup cppflags.
20316
20317         if ! which $CC > /dev/null 2>&1; then
20318                 skip_env "$CC is not installed"
20319         fi
20320
20321         for header in $prefix/*.h; do
20322                 if ! [[ -f "$header" ]]; then
20323                         continue
20324                 fi
20325
20326                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
20327                         continue # lustre_ioctl.h is internal header
20328                 fi
20329
20330                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
20331                         error "cannot compile '$header'"
20332         done
20333         rm -f $out
20334 }
20335 run_test 400b "packaged headers can be compiled"
20336
20337 test_401a() { #LU-7437
20338         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
20339         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
20340
20341         #count the number of parameters by "list_param -R"
20342         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
20343         #count the number of parameters by listing proc files
20344         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
20345         echo "proc_dirs='$proc_dirs'"
20346         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
20347         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
20348                       sort -u | wc -l)
20349
20350         [ $params -eq $procs ] ||
20351                 error "found $params parameters vs. $procs proc files"
20352
20353         # test the list_param -D option only returns directories
20354         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
20355         #count the number of parameters by listing proc directories
20356         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
20357                 sort -u | wc -l)
20358
20359         [ $params -eq $procs ] ||
20360                 error "found $params parameters vs. $procs proc files"
20361 }
20362 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
20363
20364 test_401b() {
20365         local save=$($LCTL get_param -n jobid_var)
20366         local tmp=testing
20367
20368         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
20369                 error "no error returned when setting bad parameters"
20370
20371         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
20372         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
20373
20374         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
20375         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
20376         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
20377 }
20378 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
20379
20380 test_401c() {
20381         local jobid_var_old=$($LCTL get_param -n jobid_var)
20382         local jobid_var_new
20383
20384         $LCTL set_param jobid_var= &&
20385                 error "no error returned for 'set_param a='"
20386
20387         jobid_var_new=$($LCTL get_param -n jobid_var)
20388         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20389                 error "jobid_var was changed by setting without value"
20390
20391         $LCTL set_param jobid_var &&
20392                 error "no error returned for 'set_param a'"
20393
20394         jobid_var_new=$($LCTL get_param -n jobid_var)
20395         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20396                 error "jobid_var was changed by setting without value"
20397 }
20398 run_test 401c "Verify 'lctl set_param' without value fails in either format."
20399
20400 test_401d() {
20401         local jobid_var_old=$($LCTL get_param -n jobid_var)
20402         local jobid_var_new
20403         local new_value="foo=bar"
20404
20405         $LCTL set_param jobid_var=$new_value ||
20406                 error "'set_param a=b' did not accept a value containing '='"
20407
20408         jobid_var_new=$($LCTL get_param -n jobid_var)
20409         [[ "$jobid_var_new" == "$new_value" ]] ||
20410                 error "'set_param a=b' failed on a value containing '='"
20411
20412         # Reset the jobid_var to test the other format
20413         $LCTL set_param jobid_var=$jobid_var_old
20414         jobid_var_new=$($LCTL get_param -n jobid_var)
20415         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20416                 error "failed to reset jobid_var"
20417
20418         $LCTL set_param jobid_var $new_value ||
20419                 error "'set_param a b' did not accept a value containing '='"
20420
20421         jobid_var_new=$($LCTL get_param -n jobid_var)
20422         [[ "$jobid_var_new" == "$new_value" ]] ||
20423                 error "'set_param a b' failed on a value containing '='"
20424
20425         $LCTL set_param jobid_var $jobid_var_old
20426         jobid_var_new=$($LCTL get_param -n jobid_var)
20427         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20428                 error "failed to reset jobid_var"
20429 }
20430 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
20431
20432 test_402() {
20433         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
20434         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
20435                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
20436         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
20437                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
20438                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
20439         remote_mds_nodsh && skip "remote MDS with nodsh"
20440
20441         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
20442 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
20443         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
20444         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
20445                 echo "Touch failed - OK"
20446 }
20447 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
20448
20449 test_403() {
20450         local file1=$DIR/$tfile.1
20451         local file2=$DIR/$tfile.2
20452         local tfile=$TMP/$tfile
20453
20454         rm -f $file1 $file2 $tfile
20455
20456         touch $file1
20457         ln $file1 $file2
20458
20459         # 30 sec OBD_TIMEOUT in ll_getattr()
20460         # right before populating st_nlink
20461         $LCTL set_param fail_loc=0x80001409
20462         stat -c %h $file1 > $tfile &
20463
20464         # create an alias, drop all locks and reclaim the dentry
20465         < $file2
20466         cancel_lru_locks mdc
20467         cancel_lru_locks osc
20468         sysctl -w vm.drop_caches=2
20469
20470         wait
20471
20472         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
20473
20474         rm -f $tfile $file1 $file2
20475 }
20476 run_test 403 "i_nlink should not drop to zero due to aliasing"
20477
20478 test_404() { # LU-6601
20479         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
20480                 skip "Need server version newer than 2.8.52"
20481         remote_mds_nodsh && skip "remote MDS with nodsh"
20482
20483         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
20484                 awk '/osp .*-osc-MDT/ { print $4}')
20485
20486         local osp
20487         for osp in $mosps; do
20488                 echo "Deactivate: " $osp
20489                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
20490                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20491                         awk -vp=$osp '$4 == p { print $2 }')
20492                 [ $stat = IN ] || {
20493                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20494                         error "deactivate error"
20495                 }
20496                 echo "Activate: " $osp
20497                 do_facet $SINGLEMDS $LCTL --device %$osp activate
20498                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20499                         awk -vp=$osp '$4 == p { print $2 }')
20500                 [ $stat = UP ] || {
20501                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20502                         error "activate error"
20503                 }
20504         done
20505 }
20506 run_test 404 "validate manual {de}activated works properly for OSPs"
20507
20508 test_405() {
20509         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20510         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
20511                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
20512                         skip "Layout swap lock is not supported"
20513
20514         check_swap_layouts_support
20515
20516         test_mkdir $DIR/$tdir
20517         swap_lock_test -d $DIR/$tdir ||
20518                 error "One layout swap locked test failed"
20519 }
20520 run_test 405 "Various layout swap lock tests"
20521
20522 test_406() {
20523         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20524         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20525         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20527         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
20528                 skip "Need MDS version at least 2.8.50"
20529
20530         local def_stripe_size=$($LFS getstripe -S $MOUNT)
20531         local test_pool=$TESTNAME
20532
20533         pool_add $test_pool || error "pool_add failed"
20534         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
20535                 error "pool_add_targets failed"
20536
20537         save_layout_restore_at_exit $MOUNT
20538
20539         # parent set default stripe count only, child will stripe from both
20540         # parent and fs default
20541         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
20542                 error "setstripe $MOUNT failed"
20543         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
20544         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
20545         for i in $(seq 10); do
20546                 local f=$DIR/$tdir/$tfile.$i
20547                 touch $f || error "touch failed"
20548                 local count=$($LFS getstripe -c $f)
20549                 [ $count -eq $OSTCOUNT ] ||
20550                         error "$f stripe count $count != $OSTCOUNT"
20551                 local offset=$($LFS getstripe -i $f)
20552                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
20553                 local size=$($LFS getstripe -S $f)
20554                 [ $size -eq $((def_stripe_size * 2)) ] ||
20555                         error "$f stripe size $size != $((def_stripe_size * 2))"
20556                 local pool=$($LFS getstripe -p $f)
20557                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
20558         done
20559
20560         # change fs default striping, delete parent default striping, now child
20561         # will stripe from new fs default striping only
20562         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
20563                 error "change $MOUNT default stripe failed"
20564         $LFS setstripe -c 0 $DIR/$tdir ||
20565                 error "delete $tdir default stripe failed"
20566         for i in $(seq 11 20); do
20567                 local f=$DIR/$tdir/$tfile.$i
20568                 touch $f || error "touch $f failed"
20569                 local count=$($LFS getstripe -c $f)
20570                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
20571                 local offset=$($LFS getstripe -i $f)
20572                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
20573                 local size=$($LFS getstripe -S $f)
20574                 [ $size -eq $def_stripe_size ] ||
20575                         error "$f stripe size $size != $def_stripe_size"
20576                 local pool=$($LFS getstripe -p $f)
20577                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
20578         done
20579
20580         unlinkmany $DIR/$tdir/$tfile. 1 20
20581
20582         local f=$DIR/$tdir/$tfile
20583         pool_remove_all_targets $test_pool $f
20584         pool_remove $test_pool $f
20585 }
20586 run_test 406 "DNE support fs default striping"
20587
20588 test_407() {
20589         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20590         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20591                 skip "Need MDS version at least 2.8.55"
20592         remote_mds_nodsh && skip "remote MDS with nodsh"
20593
20594         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
20595                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
20596         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
20597                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
20598         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
20599
20600         #define OBD_FAIL_DT_TXN_STOP    0x2019
20601         for idx in $(seq $MDSCOUNT); do
20602                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
20603         done
20604         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
20605         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
20606                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
20607         true
20608 }
20609 run_test 407 "transaction fail should cause operation fail"
20610
20611 test_408() {
20612         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20613
20614         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
20615         lctl set_param fail_loc=0x8000040a
20616         # let ll_prepare_partial_page() fail
20617         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
20618
20619         rm -f $DIR/$tfile
20620
20621         # create at least 100 unused inodes so that
20622         # shrink_icache_memory(0) should not return 0
20623         touch $DIR/$tfile-{0..100}
20624         rm -f $DIR/$tfile-{0..100}
20625         sync
20626
20627         echo 2 > /proc/sys/vm/drop_caches
20628 }
20629 run_test 408 "drop_caches should not hang due to page leaks"
20630
20631 test_409()
20632 {
20633         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20634
20635         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
20636         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
20637         touch $DIR/$tdir/guard || error "(2) Fail to create"
20638
20639         local PREFIX=$(str_repeat 'A' 128)
20640         echo "Create 1K hard links start at $(date)"
20641         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20642                 error "(3) Fail to hard link"
20643
20644         echo "Links count should be right although linkEA overflow"
20645         stat $DIR/$tdir/guard || error "(4) Fail to stat"
20646         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
20647         [ $linkcount -eq 1001 ] ||
20648                 error "(5) Unexpected hard links count: $linkcount"
20649
20650         echo "List all links start at $(date)"
20651         ls -l $DIR/$tdir/foo > /dev/null ||
20652                 error "(6) Fail to list $DIR/$tdir/foo"
20653
20654         echo "Unlink hard links start at $(date)"
20655         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20656                 error "(7) Fail to unlink"
20657         echo "Unlink hard links finished at $(date)"
20658 }
20659 run_test 409 "Large amount of cross-MDTs hard links on the same file"
20660
20661 test_410()
20662 {
20663         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
20664                 skip "Need client version at least 2.9.59"
20665
20666         # Create a file, and stat it from the kernel
20667         local testfile=$DIR/$tfile
20668         touch $testfile
20669
20670         local run_id=$RANDOM
20671         local my_ino=$(stat --format "%i" $testfile)
20672
20673         # Try to insert the module. This will always fail as the
20674         # module is designed to not be inserted.
20675         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
20676             &> /dev/null
20677
20678         # Anything but success is a test failure
20679         dmesg | grep -q \
20680             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
20681             error "no inode match"
20682 }
20683 run_test 410 "Test inode number returned from kernel thread"
20684
20685 cleanup_test411_cgroup() {
20686         trap 0
20687         rmdir "$1"
20688 }
20689
20690 test_411() {
20691         local cg_basedir=/sys/fs/cgroup/memory
20692         # LU-9966
20693         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
20694                 skip "no setup for cgroup"
20695
20696         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
20697                 error "test file creation failed"
20698         cancel_lru_locks osc
20699
20700         # Create a very small memory cgroup to force a slab allocation error
20701         local cgdir=$cg_basedir/osc_slab_alloc
20702         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
20703         trap "cleanup_test411_cgroup $cgdir" EXIT
20704         echo 2M > $cgdir/memory.kmem.limit_in_bytes
20705         echo 1M > $cgdir/memory.limit_in_bytes
20706
20707         # Should not LBUG, just be killed by oom-killer
20708         # dd will return 0 even allocation failure in some environment.
20709         # So don't check return value
20710         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
20711         cleanup_test411_cgroup $cgdir
20712
20713         return 0
20714 }
20715 run_test 411 "Slab allocation error with cgroup does not LBUG"
20716
20717 test_412() {
20718         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20719         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20720                 skip "Need server version at least 2.10.55"
20721         fi
20722
20723         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
20724                 error "mkdir failed"
20725         $LFS getdirstripe $DIR/$tdir
20726         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20727         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
20728                 error "expect $((MDSCOUT - 1)) get $stripe_index"
20729         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
20730         [ $stripe_count -eq 2 ] ||
20731                 error "expect 2 get $stripe_count"
20732 }
20733 run_test 412 "mkdir on specific MDTs"
20734
20735 test_413a() {
20736         [ $MDSCOUNT -lt 2 ] &&
20737                 skip "We need at least 2 MDTs for this test"
20738
20739         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20740                 skip "Need server version at least 2.10.55"
20741         fi
20742
20743         mkdir $DIR/$tdir || error "mkdir failed"
20744
20745         # find MDT that is the most full
20746         local max=$($LFS df | grep MDT |
20747                 awk 'BEGIN { a=0 }
20748                         { sub("%", "", $5)
20749                           if (0+$5 >= a)
20750                           {
20751                                 a = $5
20752                                 b = $6
20753                           }
20754                         }
20755                      END { split(b, c, ":")
20756                            sub("]", "", c[2])
20757                            print c[2]
20758                          }')
20759
20760         for i in $(seq $((MDSCOUNT - 1))); do
20761                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
20762                         error "mkdir d$i failed"
20763                 $LFS getdirstripe $DIR/$tdir/d$i
20764                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
20765                 [ $stripe_index -ne $max ] ||
20766                         error "don't expect $max"
20767         done
20768 }
20769 run_test 413a "mkdir on less full MDTs"
20770
20771 test_413b() {
20772         [ $MDSCOUNT -lt 2 ] &&
20773                 skip "We need at least 2 MDTs for this test"
20774
20775         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
20776                 skip "Need server version at least 2.12.52"
20777
20778         mkdir $DIR/$tdir || error "mkdir failed"
20779         $LFS setdirstripe -D -i -1 -H space $DIR/$tdir ||
20780                 error "setdirstripe failed"
20781
20782         local qos_prio_free
20783         local qos_threshold_rr
20784         local count
20785
20786         qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
20787         qos_prio_free=${qos_prio_free%%%}
20788         qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr | head -n1)
20789         qos_threshold_rr=${qos_threshold_rr%%%}
20790         qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
20791
20792         stack_trap "$LCTL set_param lmv.*.qos_prio_free=$qos_prio_free" EXIT
20793         stack_trap "$LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr" \
20794                 EXIT
20795         stack_trap "$LCTL set_param lmv.*.qos_maxage=$qos_maxage" EXIT
20796
20797         echo "mkdir with roundrobin"
20798
20799         $LCTL set_param lmv.*.qos_threshold_rr=100
20800         for i in $(seq $((100 * MDSCOUNT))); do
20801                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20802         done
20803         for i in $(seq $MDSCOUNT); do
20804                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20805                         wc -w)
20806                 echo "$count directories created on MDT$((i - 1))"
20807                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
20808         done
20809
20810         rm -rf $DIR/$tdir/*
20811
20812         $LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr
20813         # Shorten statfs result age, so that it can be updated in time
20814         $LCTL set_param lmv.*.qos_maxage=1
20815         sleep_maxage
20816
20817         local ffree
20818         local bavail
20819         local max
20820         local min
20821         local max_index
20822         local min_index
20823         local tmp
20824
20825         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
20826         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
20827         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
20828
20829         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
20830         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
20831         max_index=0
20832         min_index=0
20833         for ((i = 1; i < ${#ffree[@]}; i++)); do
20834                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
20835                 if [ $tmp -gt $max ]; then
20836                         max=$tmp
20837                         max_index=$i
20838                 fi
20839                 if [ $tmp -lt $min ]; then
20840                         min=$tmp
20841                         min_index=$i
20842                 fi
20843         done
20844
20845         [ ${ffree[min_index]} -eq 0 ] &&
20846                 skip "no free files in MDT$min_index"
20847         [ ${ffree[min_index]} -gt 100000000 ] &&
20848                 skip "too much free files in MDT$min_index"
20849
20850         # Check if we need to generate uneven MDTs
20851         local threshold=50
20852         local diff=$(((max - min ) * 100 / min))
20853         local value="$(generate_string 1024)"
20854         local i
20855
20856         while [ $diff -lt $threshold ]; do
20857                 # generate uneven MDTs, create till $threshold% diff
20858                 echo -n "weight diff=$diff% must be > $threshold% ..."
20859                 count=$((${ffree[min_index]} / 10))
20860                 # 50 sec per 10000 files in vm
20861                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
20862                         skip "$count files to create"
20863                 echo "Fill MDT$min_index with $count files"
20864                 [ -d $DIR/$tdir-MDT$min_index ] ||
20865                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
20866                         error "mkdir $tdir-MDT$min_index failed"
20867                 for i in $(seq $count); do
20868                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
20869                                 $DIR/$tdir-MDT$min_index/f$i > /dev/null ||
20870                                 error "create f$i failed"
20871                         setfattr -n user.413b -v $value \
20872                                 $DIR/$tdir-MDT$min_index/f$i ||
20873                                 error "setfattr f$i failed"
20874                 done
20875
20876                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
20877                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
20878                 max=$(((${ffree[max_index]} >> 8) * \
20879                         (${bavail[max_index]} * bsize >> 16)))
20880                 min=$(((${ffree[min_index]} >> 8) * \
20881                         (${bavail[min_index]} * bsize >> 16)))
20882                 diff=$(((max - min) * 100 / min))
20883         done
20884
20885         echo "MDT filesfree available: ${ffree[@]}"
20886         echo "MDT blocks available: ${bavail[@]}"
20887         echo "weight diff=$diff%"
20888
20889         echo "mkdir with balanced space usage"
20890         $LCTL set_param lmv.*.qos_prio_free=100
20891         for i in $(seq $((100 * MDSCOUNT))); do
20892                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20893         done
20894
20895         for i in $(seq $MDSCOUNT); do
20896                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20897                         wc -w)
20898                 echo "$count directories created on MDT$((i - 1))"
20899         done
20900
20901         max=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$max_index$ | wc -l)
20902         min=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$min_index$ | wc -l)
20903
20904         [ $((max - min)) -lt 10 ] &&
20905                 error "subdirs shouldn't be evenly distributed"
20906
20907         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20908
20909         $LFS setdirstripe -D -d $DIR/$tdir || error "setdirstripe -d failed"
20910         getfattr -n trusted.dmv $DIR/$tdir &&
20911                 error "default dir layout exists" || true
20912 }
20913 run_test 413b "mkdir with balanced space usage"
20914
20915 test_414() {
20916 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
20917         $LCTL set_param fail_loc=0x80000521
20918         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
20919         rm -f $DIR/$tfile
20920 }
20921 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
20922
20923 test_415() {
20924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20925         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
20926                 skip "Need server version at least 2.11.52"
20927
20928         # LU-11102
20929         local total
20930         local setattr_pid
20931         local start_time
20932         local end_time
20933         local duration
20934
20935         total=500
20936         # this test may be slow on ZFS
20937         [ "$mds1_FSTYPE" == "zfs" ] && total=100
20938
20939         # though this test is designed for striped directory, let's test normal
20940         # directory too since lock is always saved as CoS lock.
20941         test_mkdir $DIR/$tdir || error "mkdir $tdir"
20942         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
20943
20944         (
20945                 while true; do
20946                         touch $DIR/$tdir
20947                 done
20948         ) &
20949         setattr_pid=$!
20950
20951         start_time=$(date +%s)
20952         for i in $(seq $total); do
20953                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
20954                         > /dev/null
20955         done
20956         end_time=$(date +%s)
20957         duration=$((end_time - start_time))
20958
20959         kill -9 $setattr_pid
20960
20961         echo "rename $total files took $duration sec"
20962         [ $duration -lt 100 ] || error "rename took $duration sec"
20963 }
20964 run_test 415 "lock revoke is not missing"
20965
20966 test_416() {
20967         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
20968                 skip "Need server version at least 2.11.55"
20969
20970         # define OBD_FAIL_OSD_TXN_START    0x19a
20971         do_facet mds1 lctl set_param fail_loc=0x19a
20972
20973         lfs mkdir -c $MDSCOUNT $DIR/$tdir
20974
20975         true
20976 }
20977 run_test 416 "transaction start failure won't cause system hung"
20978
20979 cleanup_417() {
20980         trap 0
20981         do_nodes $(comma_list $(mdts_nodes)) \
20982                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
20983         do_nodes $(comma_list $(mdts_nodes)) \
20984                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
20985         do_nodes $(comma_list $(mdts_nodes)) \
20986                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
20987 }
20988
20989 test_417() {
20990         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20991         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
20992                 skip "Need MDS version at least 2.11.56"
20993
20994         trap cleanup_417 RETURN EXIT
20995
20996         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
20997         do_nodes $(comma_list $(mdts_nodes)) \
20998                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
20999         $LFS migrate -m 0 $DIR/$tdir.1 &&
21000                 error "migrate dir $tdir.1 should fail"
21001
21002         do_nodes $(comma_list $(mdts_nodes)) \
21003                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
21004         $LFS mkdir -i 1 $DIR/$tdir.2 &&
21005                 error "create remote dir $tdir.2 should fail"
21006
21007         do_nodes $(comma_list $(mdts_nodes)) \
21008                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
21009         $LFS mkdir -c 2 $DIR/$tdir.3 &&
21010                 error "create striped dir $tdir.3 should fail"
21011         true
21012 }
21013 run_test 417 "disable remote dir, striped dir and dir migration"
21014
21015 # Checks that the outputs of df [-i] and lfs df [-i] match
21016 #
21017 # usage: check_lfs_df <blocks | inodes> <mountpoint>
21018 check_lfs_df() {
21019         local dir=$2
21020         local inodes
21021         local df_out
21022         local lfs_df_out
21023         local count
21024         local passed=false
21025
21026         # blocks or inodes
21027         [ "$1" == "blocks" ] && inodes= || inodes="-i"
21028
21029         for count in {1..100}; do
21030                 cancel_lru_locks
21031                 sync; sleep 0.2
21032
21033                 # read the lines of interest
21034                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
21035                         error "df $inodes $dir | tail -n +2 failed"
21036                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
21037                         error "lfs df $inodes $dir | grep summary: failed"
21038
21039                 # skip first substrings of each output as they are different
21040                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
21041                 # compare the two outputs
21042                 passed=true
21043                 for i in {1..5}; do
21044                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
21045                 done
21046                 $passed && break
21047         done
21048
21049         if ! $passed; then
21050                 df -P $inodes $dir
21051                 echo
21052                 lfs df $inodes $dir
21053                 error "df and lfs df $1 output mismatch: "      \
21054                       "df ${inodes}: ${df_out[*]}, "            \
21055                       "lfs df ${inodes}: ${lfs_df_out[*]}"
21056         fi
21057 }
21058
21059 test_418() {
21060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21061
21062         local dir=$DIR/$tdir
21063         local numfiles=$((RANDOM % 4096 + 2))
21064         local numblocks=$((RANDOM % 256 + 1))
21065
21066         wait_delete_completed
21067         test_mkdir $dir
21068
21069         # check block output
21070         check_lfs_df blocks $dir
21071         # check inode output
21072         check_lfs_df inodes $dir
21073
21074         # create a single file and retest
21075         echo "Creating a single file and testing"
21076         createmany -o $dir/$tfile- 1 &>/dev/null ||
21077                 error "creating 1 file in $dir failed"
21078         check_lfs_df blocks $dir
21079         check_lfs_df inodes $dir
21080
21081         # create a random number of files
21082         echo "Creating $((numfiles - 1)) files and testing"
21083         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
21084                 error "creating $((numfiles - 1)) files in $dir failed"
21085
21086         # write a random number of blocks to the first test file
21087         echo "Writing $numblocks 4K blocks and testing"
21088         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
21089                 count=$numblocks &>/dev/null ||
21090                 error "dd to $dir/${tfile}-0 failed"
21091
21092         # retest
21093         check_lfs_df blocks $dir
21094         check_lfs_df inodes $dir
21095
21096         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
21097                 error "unlinking $numfiles files in $dir failed"
21098 }
21099 run_test 418 "df and lfs df outputs match"
21100
21101 test_419()
21102 {
21103         local dir=$DIR/$tdir
21104
21105         mkdir -p $dir
21106         touch $dir/file
21107
21108         cancel_lru_locks mdc
21109
21110         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
21111         $LCTL set_param fail_loc=0x1410
21112         cat $dir/file
21113         $LCTL set_param fail_loc=0
21114         rm -rf $dir
21115 }
21116 run_test 419 "Verify open file by name doesn't crash kernel"
21117
21118 test_420()
21119 {
21120         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
21121                 skip "Need MDS version at least 2.12.53"
21122
21123         local SAVE_UMASK=$(umask)
21124         local dir=$DIR/$tdir
21125         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
21126
21127         mkdir -p $dir
21128         umask 0000
21129         mkdir -m03777 $dir/testdir
21130         ls -dn $dir/testdir
21131         # Need to remove trailing '.' when SELinux is enabled
21132         local dirperms=$(ls -dn $dir/testdir |
21133                          awk '{ sub(/\.$/, "", $1); print $1}')
21134         [ $dirperms == "drwxrwsrwt" ] ||
21135                 error "incorrect perms on $dir/testdir"
21136
21137         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
21138                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
21139         ls -n $dir/testdir/testfile
21140         local fileperms=$(ls -n $dir/testdir/testfile |
21141                           awk '{ sub(/\.$/, "", $1); print $1}')
21142         [ $fileperms == "-rwxr-xr-x" ] ||
21143                 error "incorrect perms on $dir/testdir/testfile"
21144
21145         umask $SAVE_UMASK
21146 }
21147 run_test 420 "clear SGID bit on non-directories for non-members"
21148
21149 test_421a() {
21150         local cnt
21151         local fid1
21152         local fid2
21153
21154         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21155                 skip "Need MDS version at least 2.12.54"
21156
21157         test_mkdir $DIR/$tdir
21158         createmany -o $DIR/$tdir/f 3
21159         cnt=$(ls -1 $DIR/$tdir | wc -l)
21160         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21161
21162         fid1=$(lfs path2fid $DIR/$tdir/f1)
21163         fid2=$(lfs path2fid $DIR/$tdir/f2)
21164         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
21165
21166         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
21167         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
21168
21169         cnt=$(ls -1 $DIR/$tdir | wc -l)
21170         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21171
21172         rm -f $DIR/$tdir/f3 || error "can't remove f3"
21173         createmany -o $DIR/$tdir/f 3
21174         cnt=$(ls -1 $DIR/$tdir | wc -l)
21175         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21176
21177         fid1=$(lfs path2fid $DIR/$tdir/f1)
21178         fid2=$(lfs path2fid $DIR/$tdir/f2)
21179         echo "remove using fsname $FSNAME"
21180         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
21181
21182         cnt=$(ls -1 $DIR/$tdir | wc -l)
21183         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21184 }
21185 run_test 421a "simple rm by fid"
21186
21187 test_421b() {
21188         local cnt
21189         local FID1
21190         local FID2
21191
21192         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21193                 skip "Need MDS version at least 2.12.54"
21194
21195         test_mkdir $DIR/$tdir
21196         createmany -o $DIR/$tdir/f 3
21197         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
21198         MULTIPID=$!
21199
21200         FID1=$(lfs path2fid $DIR/$tdir/f1)
21201         FID2=$(lfs path2fid $DIR/$tdir/f2)
21202         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
21203
21204         kill -USR1 $MULTIPID
21205         wait
21206
21207         cnt=$(ls $DIR/$tdir | wc -l)
21208         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
21209 }
21210 run_test 421b "rm by fid on open file"
21211
21212 test_421c() {
21213         local cnt
21214         local FIDS
21215
21216         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21217                 skip "Need MDS version at least 2.12.54"
21218
21219         test_mkdir $DIR/$tdir
21220         createmany -o $DIR/$tdir/f 3
21221         touch $DIR/$tdir/$tfile
21222         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
21223         cnt=$(ls -1 $DIR/$tdir | wc -l)
21224         [ $cnt != 184 ] && error "unexpected #files: $cnt"
21225
21226         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
21227         $LFS rmfid $DIR $FID1 || error "rmfid failed"
21228
21229         cnt=$(ls $DIR/$tdir | wc -l)
21230         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
21231 }
21232 run_test 421c "rm by fid against hardlinked files"
21233
21234 test_421d() {
21235         local cnt
21236         local FIDS
21237
21238         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21239                 skip "Need MDS version at least 2.12.54"
21240
21241         test_mkdir $DIR/$tdir
21242         createmany -o $DIR/$tdir/f 4097
21243         cnt=$(ls -1 $DIR/$tdir | wc -l)
21244         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
21245
21246         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
21247         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21248
21249         cnt=$(ls $DIR/$tdir | wc -l)
21250         rm -rf $DIR/$tdir
21251         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21252 }
21253 run_test 421d "rmfid en masse"
21254
21255 test_421e() {
21256         local cnt
21257         local FID
21258
21259         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21260         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21261                 skip "Need MDS version at least 2.12.54"
21262
21263         mkdir -p $DIR/$tdir
21264         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21265         createmany -o $DIR/$tdir/striped_dir/f 512
21266         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21267         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21268
21269         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21270                 sed "s/[/][^:]*://g")
21271         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21272
21273         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21274         rm -rf $DIR/$tdir
21275         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21276 }
21277 run_test 421e "rmfid in DNE"
21278
21279 test_421f() {
21280         local cnt
21281         local FID
21282
21283         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21284                 skip "Need MDS version at least 2.12.54"
21285
21286         test_mkdir $DIR/$tdir
21287         touch $DIR/$tdir/f
21288         cnt=$(ls -1 $DIR/$tdir | wc -l)
21289         [ $cnt != 1 ] && error "unexpected #files: $cnt"
21290
21291         FID=$(lfs path2fid $DIR/$tdir/f)
21292         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
21293         # rmfid should fail
21294         cnt=$(ls -1 $DIR/$tdir | wc -l)
21295         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
21296
21297         chmod a+rw $DIR/$tdir
21298         ls -la $DIR/$tdir
21299         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
21300         # rmfid should fail
21301         cnt=$(ls -1 $DIR/$tdir | wc -l)
21302         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
21303
21304         rm -f $DIR/$tdir/f
21305         $RUNAS touch $DIR/$tdir/f
21306         FID=$(lfs path2fid $DIR/$tdir/f)
21307         echo "rmfid as root"
21308         $LFS rmfid $DIR $FID || error "rmfid as root failed"
21309         cnt=$(ls -1 $DIR/$tdir | wc -l)
21310         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
21311
21312         rm -f $DIR/$tdir/f
21313         $RUNAS touch $DIR/$tdir/f
21314         cnt=$(ls -1 $DIR/$tdir | wc -l)
21315         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
21316         FID=$(lfs path2fid $DIR/$tdir/f)
21317         # rmfid w/o user_fid2path mount option should fail
21318         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
21319         cnt=$(ls -1 $DIR/$tdir | wc -l)
21320         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
21321
21322         umount_client $MOUNT || error "failed to umount client"
21323         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
21324                 error "failed to mount client'"
21325
21326         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
21327         # rmfid should succeed
21328         cnt=$(ls -1 $DIR/$tdir | wc -l)
21329         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
21330
21331         # rmfid shouldn't allow to remove files due to dir's permission
21332         chmod a+rwx $DIR/$tdir
21333         touch $DIR/$tdir/f
21334         ls -la $DIR/$tdir
21335         FID=$(lfs path2fid $DIR/$tdir/f)
21336         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
21337
21338         umount_client $MOUNT || error "failed to umount client"
21339         mount_client $MOUNT "$MOUNT_OPTS" ||
21340                 error "failed to mount client'"
21341
21342 }
21343 run_test 421f "rmfid checks permissions"
21344
21345 test_421g() {
21346         local cnt
21347         local FIDS
21348
21349         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21350         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21351                 skip "Need MDS version at least 2.12.54"
21352
21353         mkdir -p $DIR/$tdir
21354         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21355         createmany -o $DIR/$tdir/striped_dir/f 512
21356         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21357         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21358
21359         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21360                 sed "s/[/][^:]*://g")
21361
21362         rm -f $DIR/$tdir/striped_dir/f1*
21363         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21364         removed=$((512 - cnt))
21365
21366         # few files have been just removed, so we expect
21367         # rmfid to fail on their fids
21368         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
21369         [ $removed != $errors ] && error "$errors != $removed"
21370
21371         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21372         rm -rf $DIR/$tdir
21373         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21374 }
21375 run_test 421g "rmfid to return errors properly"
21376
21377 test_422() {
21378         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
21379         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
21380         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
21381         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
21382         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
21383
21384         local amc=$(at_max_get client)
21385         local amo=$(at_max_get mds1)
21386         local timeout=`lctl get_param -n timeout`
21387
21388         at_max_set 0 client
21389         at_max_set 0 mds1
21390
21391 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
21392         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
21393                         fail_val=$(((2*timeout + 10)*1000))
21394         touch $DIR/$tdir/d3/file &
21395         sleep 2
21396 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
21397         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
21398                         fail_val=$((2*timeout + 5))
21399         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
21400         local pid=$!
21401         sleep 1
21402         kill -9 $pid
21403         sleep $((2 * timeout))
21404         echo kill $pid
21405         kill -9 $pid
21406         lctl mark touch
21407         touch $DIR/$tdir/d2/file3
21408         touch $DIR/$tdir/d2/file4
21409         touch $DIR/$tdir/d2/file5
21410
21411         wait
21412         at_max_set $amc client
21413         at_max_set $amo mds1
21414 }
21415 run_test 422 "kill a process with RPC in progress"
21416
21417 prep_801() {
21418         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21419         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21420                 skip "Need server version at least 2.9.55"
21421
21422         start_full_debug_logging
21423 }
21424
21425 post_801() {
21426         stop_full_debug_logging
21427 }
21428
21429 barrier_stat() {
21430         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21431                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21432                            awk '/The barrier for/ { print $7 }')
21433                 echo $st
21434         else
21435                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
21436                 echo \'$st\'
21437         fi
21438 }
21439
21440 barrier_expired() {
21441         local expired
21442
21443         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21444                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21445                           awk '/will be expired/ { print $7 }')
21446         else
21447                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
21448         fi
21449
21450         echo $expired
21451 }
21452
21453 test_801a() {
21454         prep_801
21455
21456         echo "Start barrier_freeze at: $(date)"
21457         #define OBD_FAIL_BARRIER_DELAY          0x2202
21458         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21459         # Do not reduce barrier time - See LU-11873
21460         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
21461
21462         sleep 2
21463         local b_status=$(barrier_stat)
21464         echo "Got barrier status at: $(date)"
21465         [ "$b_status" = "'freezing_p1'" ] ||
21466                 error "(1) unexpected barrier status $b_status"
21467
21468         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21469         wait
21470         b_status=$(barrier_stat)
21471         [ "$b_status" = "'frozen'" ] ||
21472                 error "(2) unexpected barrier status $b_status"
21473
21474         local expired=$(barrier_expired)
21475         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
21476         sleep $((expired + 3))
21477
21478         b_status=$(barrier_stat)
21479         [ "$b_status" = "'expired'" ] ||
21480                 error "(3) unexpected barrier status $b_status"
21481
21482         # Do not reduce barrier time - See LU-11873
21483         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
21484                 error "(4) fail to freeze barrier"
21485
21486         b_status=$(barrier_stat)
21487         [ "$b_status" = "'frozen'" ] ||
21488                 error "(5) unexpected barrier status $b_status"
21489
21490         echo "Start barrier_thaw at: $(date)"
21491         #define OBD_FAIL_BARRIER_DELAY          0x2202
21492         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21493         do_facet mgs $LCTL barrier_thaw $FSNAME &
21494
21495         sleep 2
21496         b_status=$(barrier_stat)
21497         echo "Got barrier status at: $(date)"
21498         [ "$b_status" = "'thawing'" ] ||
21499                 error "(6) unexpected barrier status $b_status"
21500
21501         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21502         wait
21503         b_status=$(barrier_stat)
21504         [ "$b_status" = "'thawed'" ] ||
21505                 error "(7) unexpected barrier status $b_status"
21506
21507         #define OBD_FAIL_BARRIER_FAILURE        0x2203
21508         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
21509         do_facet mgs $LCTL barrier_freeze $FSNAME
21510
21511         b_status=$(barrier_stat)
21512         [ "$b_status" = "'failed'" ] ||
21513                 error "(8) unexpected barrier status $b_status"
21514
21515         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21516         do_facet mgs $LCTL barrier_thaw $FSNAME
21517
21518         post_801
21519 }
21520 run_test 801a "write barrier user interfaces and stat machine"
21521
21522 test_801b() {
21523         prep_801
21524
21525         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21526         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
21527         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
21528         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
21529         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
21530
21531         cancel_lru_locks mdc
21532
21533         # 180 seconds should be long enough
21534         do_facet mgs $LCTL barrier_freeze $FSNAME 180
21535
21536         local b_status=$(barrier_stat)
21537         [ "$b_status" = "'frozen'" ] ||
21538                 error "(6) unexpected barrier status $b_status"
21539
21540         mkdir $DIR/$tdir/d0/d10 &
21541         mkdir_pid=$!
21542
21543         touch $DIR/$tdir/d1/f13 &
21544         touch_pid=$!
21545
21546         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
21547         ln_pid=$!
21548
21549         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
21550         mv_pid=$!
21551
21552         rm -f $DIR/$tdir/d4/f12 &
21553         rm_pid=$!
21554
21555         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
21556
21557         # To guarantee taht the 'stat' is not blocked
21558         b_status=$(barrier_stat)
21559         [ "$b_status" = "'frozen'" ] ||
21560                 error "(8) unexpected barrier status $b_status"
21561
21562         # let above commands to run at background
21563         sleep 5
21564
21565         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
21566         ps -p $touch_pid || error "(10) touch should be blocked"
21567         ps -p $ln_pid || error "(11) link should be blocked"
21568         ps -p $mv_pid || error "(12) rename should be blocked"
21569         ps -p $rm_pid || error "(13) unlink should be blocked"
21570
21571         b_status=$(barrier_stat)
21572         [ "$b_status" = "'frozen'" ] ||
21573                 error "(14) unexpected barrier status $b_status"
21574
21575         do_facet mgs $LCTL barrier_thaw $FSNAME
21576         b_status=$(barrier_stat)
21577         [ "$b_status" = "'thawed'" ] ||
21578                 error "(15) unexpected barrier status $b_status"
21579
21580         wait $mkdir_pid || error "(16) mkdir should succeed"
21581         wait $touch_pid || error "(17) touch should succeed"
21582         wait $ln_pid || error "(18) link should succeed"
21583         wait $mv_pid || error "(19) rename should succeed"
21584         wait $rm_pid || error "(20) unlink should succeed"
21585
21586         post_801
21587 }
21588 run_test 801b "modification will be blocked by write barrier"
21589
21590 test_801c() {
21591         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21592
21593         prep_801
21594
21595         stop mds2 || error "(1) Fail to stop mds2"
21596
21597         do_facet mgs $LCTL barrier_freeze $FSNAME 30
21598
21599         local b_status=$(barrier_stat)
21600         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
21601                 do_facet mgs $LCTL barrier_thaw $FSNAME
21602                 error "(2) unexpected barrier status $b_status"
21603         }
21604
21605         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21606                 error "(3) Fail to rescan barrier bitmap"
21607
21608         # Do not reduce barrier time - See LU-11873
21609         do_facet mgs $LCTL barrier_freeze $FSNAME 20
21610
21611         b_status=$(barrier_stat)
21612         [ "$b_status" = "'frozen'" ] ||
21613                 error "(4) unexpected barrier status $b_status"
21614
21615         do_facet mgs $LCTL barrier_thaw $FSNAME
21616         b_status=$(barrier_stat)
21617         [ "$b_status" = "'thawed'" ] ||
21618                 error "(5) unexpected barrier status $b_status"
21619
21620         local devname=$(mdsdevname 2)
21621
21622         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
21623
21624         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21625                 error "(7) Fail to rescan barrier bitmap"
21626
21627         post_801
21628 }
21629 run_test 801c "rescan barrier bitmap"
21630
21631 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
21632 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
21633 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
21634 saved_MOUNT_OPTS=$MOUNT_OPTS
21635
21636 cleanup_802a() {
21637         trap 0
21638
21639         stopall
21640         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
21641         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
21642         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
21643         MOUNT_OPTS=$saved_MOUNT_OPTS
21644         setupall
21645 }
21646
21647 test_802a() {
21648         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
21649         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21650         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21651                 skip "Need server version at least 2.9.55"
21652
21653         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
21654
21655         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21656
21657         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21658                 error "(2) Fail to copy"
21659
21660         trap cleanup_802a EXIT
21661
21662         # sync by force before remount as readonly
21663         sync; sync_all_data; sleep 3; sync_all_data
21664
21665         stopall
21666
21667         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
21668         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
21669         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
21670
21671         echo "Mount the server as read only"
21672         setupall server_only || error "(3) Fail to start servers"
21673
21674         echo "Mount client without ro should fail"
21675         mount_client $MOUNT &&
21676                 error "(4) Mount client without 'ro' should fail"
21677
21678         echo "Mount client with ro should succeed"
21679         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
21680         mount_client $MOUNT ||
21681                 error "(5) Mount client with 'ro' should succeed"
21682
21683         echo "Modify should be refused"
21684         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21685
21686         echo "Read should be allowed"
21687         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21688                 error "(7) Read should succeed under ro mode"
21689
21690         cleanup_802a
21691 }
21692 run_test 802a "simulate readonly device"
21693
21694 test_802b() {
21695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21696         remote_mds_nodsh && skip "remote MDS with nodsh"
21697
21698         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
21699                 skip "readonly option not available"
21700
21701         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
21702
21703         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21704                 error "(2) Fail to copy"
21705
21706         # write back all cached data before setting MDT to readonly
21707         cancel_lru_locks
21708         sync_all_data
21709
21710         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
21711         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
21712
21713         echo "Modify should be refused"
21714         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21715
21716         echo "Read should be allowed"
21717         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21718                 error "(7) Read should succeed under ro mode"
21719
21720         # disable readonly
21721         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
21722 }
21723 run_test 802b "be able to set MDTs to readonly"
21724
21725 test_803() {
21726         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21727         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21728                 skip "MDS needs to be newer than 2.10.54"
21729
21730         mkdir -p $DIR/$tdir
21731         # Create some objects on all MDTs to trigger related logs objects
21732         for idx in $(seq $MDSCOUNT); do
21733                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
21734                         $DIR/$tdir/dir${idx} ||
21735                         error "Fail to create $DIR/$tdir/dir${idx}"
21736         done
21737
21738         sync; sleep 3
21739         wait_delete_completed # ensure old test cleanups are finished
21740         echo "before create:"
21741         $LFS df -i $MOUNT
21742         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21743
21744         for i in {1..10}; do
21745                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
21746                         error "Fail to create $DIR/$tdir/foo$i"
21747         done
21748
21749         sync; sleep 3
21750         echo "after create:"
21751         $LFS df -i $MOUNT
21752         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21753
21754         # allow for an llog to be cleaned up during the test
21755         [ $after_used -ge $((before_used + 10 - 1)) ] ||
21756                 error "before ($before_used) + 10 > after ($after_used)"
21757
21758         for i in {1..10}; do
21759                 rm -rf $DIR/$tdir/foo$i ||
21760                         error "Fail to remove $DIR/$tdir/foo$i"
21761         done
21762
21763         sleep 3 # avoid MDT return cached statfs
21764         wait_delete_completed
21765         echo "after unlink:"
21766         $LFS df -i $MOUNT
21767         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21768
21769         # allow for an llog to be created during the test
21770         [ $after_used -le $((before_used + 1)) ] ||
21771                 error "after ($after_used) > before ($before_used) + 1"
21772 }
21773 run_test 803 "verify agent object for remote object"
21774
21775 test_804() {
21776         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21777         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21778                 skip "MDS needs to be newer than 2.10.54"
21779         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21780
21781         mkdir -p $DIR/$tdir
21782         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
21783                 error "Fail to create $DIR/$tdir/dir0"
21784
21785         local fid=$($LFS path2fid $DIR/$tdir/dir0)
21786         local dev=$(mdsdevname 2)
21787
21788         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21789                 grep ${fid} || error "NOT found agent entry for dir0"
21790
21791         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
21792                 error "Fail to create $DIR/$tdir/dir1"
21793
21794         touch $DIR/$tdir/dir1/foo0 ||
21795                 error "Fail to create $DIR/$tdir/dir1/foo0"
21796         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
21797         local rc=0
21798
21799         for idx in $(seq $MDSCOUNT); do
21800                 dev=$(mdsdevname $idx)
21801                 do_facet mds${idx} \
21802                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21803                         grep ${fid} && rc=$idx
21804         done
21805
21806         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
21807                 error "Fail to rename foo0 to foo1"
21808         if [ $rc -eq 0 ]; then
21809                 for idx in $(seq $MDSCOUNT); do
21810                         dev=$(mdsdevname $idx)
21811                         do_facet mds${idx} \
21812                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21813                         grep ${fid} && rc=$idx
21814                 done
21815         fi
21816
21817         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
21818                 error "Fail to rename foo1 to foo2"
21819         if [ $rc -eq 0 ]; then
21820                 for idx in $(seq $MDSCOUNT); do
21821                         dev=$(mdsdevname $idx)
21822                         do_facet mds${idx} \
21823                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21824                         grep ${fid} && rc=$idx
21825                 done
21826         fi
21827
21828         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
21829
21830         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
21831                 error "Fail to link to $DIR/$tdir/dir1/foo2"
21832         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
21833                 error "Fail to rename foo2 to foo0"
21834         unlink $DIR/$tdir/dir1/foo0 ||
21835                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
21836         rm -rf $DIR/$tdir/dir0 ||
21837                 error "Fail to rm $DIR/$tdir/dir0"
21838
21839         for idx in $(seq $MDSCOUNT); do
21840                 dev=$(mdsdevname $idx)
21841                 rc=0
21842
21843                 stop mds${idx}
21844                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
21845                         rc=$?
21846                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
21847                         error "mount mds$idx failed"
21848                 df $MOUNT > /dev/null 2>&1
21849
21850                 # e2fsck should not return error
21851                 [ $rc -eq 0 ] ||
21852                         error "e2fsck detected error on MDT${idx}: rc=$rc"
21853         done
21854 }
21855 run_test 804 "verify agent entry for remote entry"
21856
21857 cleanup_805() {
21858         do_facet $SINGLEMDS zfs set quota=$old $fsset
21859         unlinkmany $DIR/$tdir/f- 1000000
21860         trap 0
21861 }
21862
21863 test_805() {
21864         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
21865         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
21866         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
21867                 skip "netfree not implemented before 0.7"
21868         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
21869                 skip "Need MDS version at least 2.10.57"
21870
21871         local fsset
21872         local freekb
21873         local usedkb
21874         local old
21875         local quota
21876         local pref="osd-zfs.lustre-MDT0000."
21877
21878         # limit available space on MDS dataset to meet nospace issue
21879         # quickly. then ZFS 0.7.2 can use reserved space if asked
21880         # properly (using netfree flag in osd_declare_destroy()
21881         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
21882         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
21883                 gawk '{print $3}')
21884         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
21885         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
21886         let "usedkb=usedkb-freekb"
21887         let "freekb=freekb/2"
21888         if let "freekb > 5000"; then
21889                 let "freekb=5000"
21890         fi
21891         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
21892         trap cleanup_805 EXIT
21893         mkdir $DIR/$tdir
21894         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
21895         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
21896         rm -rf $DIR/$tdir || error "not able to remove"
21897         do_facet $SINGLEMDS zfs set quota=$old $fsset
21898         trap 0
21899 }
21900 run_test 805 "ZFS can remove from full fs"
21901
21902 # Size-on-MDS test
21903 check_lsom_data()
21904 {
21905         local file=$1
21906         local size=$($LFS getsom -s $file)
21907         local expect=$(stat -c %s $file)
21908
21909         [[ $size == $expect ]] ||
21910                 error "$file expected size: $expect, got: $size"
21911
21912         local blocks=$($LFS getsom -b $file)
21913         expect=$(stat -c %b $file)
21914         [[ $blocks == $expect ]] ||
21915                 error "$file expected blocks: $expect, got: $blocks"
21916 }
21917
21918 check_lsom_size()
21919 {
21920         local size=$($LFS getsom -s $1)
21921         local expect=$2
21922
21923         [[ $size == $expect ]] ||
21924                 error "$file expected size: $expect, got: $size"
21925 }
21926
21927 test_806() {
21928         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21929                 skip "Need MDS version at least 2.11.52"
21930
21931         local bs=1048576
21932
21933         touch $DIR/$tfile || error "touch $tfile failed"
21934
21935         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21936         save_lustre_params client "llite.*.xattr_cache" > $save
21937         lctl set_param llite.*.xattr_cache=0
21938         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21939
21940         # single-threaded write
21941         echo "Test SOM for single-threaded write"
21942         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
21943                 error "write $tfile failed"
21944         check_lsom_size $DIR/$tfile $bs
21945
21946         local num=32
21947         local size=$(($num * $bs))
21948         local offset=0
21949         local i
21950
21951         echo "Test SOM for single client multi-threaded($num) write"
21952         $TRUNCATE $DIR/$tfile 0
21953         for ((i = 0; i < $num; i++)); do
21954                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21955                 local pids[$i]=$!
21956                 offset=$((offset + $bs))
21957         done
21958         for (( i=0; i < $num; i++ )); do
21959                 wait ${pids[$i]}
21960         done
21961         check_lsom_size $DIR/$tfile $size
21962
21963         $TRUNCATE $DIR/$tfile 0
21964         for ((i = 0; i < $num; i++)); do
21965                 offset=$((offset - $bs))
21966                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21967                 local pids[$i]=$!
21968         done
21969         for (( i=0; i < $num; i++ )); do
21970                 wait ${pids[$i]}
21971         done
21972         check_lsom_size $DIR/$tfile $size
21973
21974         # multi-client writes
21975         num=$(get_node_count ${CLIENTS//,/ })
21976         size=$(($num * $bs))
21977         offset=0
21978         i=0
21979
21980         echo "Test SOM for multi-client ($num) writes"
21981         $TRUNCATE $DIR/$tfile 0
21982         for client in ${CLIENTS//,/ }; do
21983                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21984                 local pids[$i]=$!
21985                 i=$((i + 1))
21986                 offset=$((offset + $bs))
21987         done
21988         for (( i=0; i < $num; i++ )); do
21989                 wait ${pids[$i]}
21990         done
21991         check_lsom_size $DIR/$tfile $offset
21992
21993         i=0
21994         $TRUNCATE $DIR/$tfile 0
21995         for client in ${CLIENTS//,/ }; do
21996                 offset=$((offset - $bs))
21997                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21998                 local pids[$i]=$!
21999                 i=$((i + 1))
22000         done
22001         for (( i=0; i < $num; i++ )); do
22002                 wait ${pids[$i]}
22003         done
22004         check_lsom_size $DIR/$tfile $size
22005
22006         # verify truncate
22007         echo "Test SOM for truncate"
22008         $TRUNCATE $DIR/$tfile 1048576
22009         check_lsom_size $DIR/$tfile 1048576
22010         $TRUNCATE $DIR/$tfile 1234
22011         check_lsom_size $DIR/$tfile 1234
22012
22013         # verify SOM blocks count
22014         echo "Verify SOM block count"
22015         $TRUNCATE $DIR/$tfile 0
22016         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
22017                 error "failed to write file $tfile"
22018         check_lsom_data $DIR/$tfile
22019 }
22020 run_test 806 "Verify Lazy Size on MDS"
22021
22022 test_807() {
22023         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22024         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22025                 skip "Need MDS version at least 2.11.52"
22026
22027         # Registration step
22028         changelog_register || error "changelog_register failed"
22029         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
22030         changelog_users $SINGLEMDS | grep -q $cl_user ||
22031                 error "User $cl_user not found in changelog_users"
22032
22033         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22034         save_lustre_params client "llite.*.xattr_cache" > $save
22035         lctl set_param llite.*.xattr_cache=0
22036         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22037
22038         rm -rf $DIR/$tdir || error "rm $tdir failed"
22039         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22040         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
22041         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
22042         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
22043                 error "truncate $tdir/trunc failed"
22044
22045         local bs=1048576
22046         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
22047                 error "write $tfile failed"
22048
22049         # multi-client wirtes
22050         local num=$(get_node_count ${CLIENTS//,/ })
22051         local offset=0
22052         local i=0
22053
22054         echo "Test SOM for multi-client ($num) writes"
22055         touch $DIR/$tfile || error "touch $tfile failed"
22056         $TRUNCATE $DIR/$tfile 0
22057         for client in ${CLIENTS//,/ }; do
22058                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22059                 local pids[$i]=$!
22060                 i=$((i + 1))
22061                 offset=$((offset + $bs))
22062         done
22063         for (( i=0; i < $num; i++ )); do
22064                 wait ${pids[$i]}
22065         done
22066
22067         sleep 5
22068         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
22069         check_lsom_data $DIR/$tdir/trunc
22070         check_lsom_data $DIR/$tdir/single_dd
22071         check_lsom_data $DIR/$tfile
22072
22073         rm -rf $DIR/$tdir
22074         # Deregistration step
22075         changelog_deregister || error "changelog_deregister failed"
22076 }
22077 run_test 807 "verify LSOM syncing tool"
22078
22079 check_som_nologged()
22080 {
22081         local lines=$($LFS changelog $FSNAME-MDT0000 |
22082                 grep 'x=trusted.som' | wc -l)
22083         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
22084 }
22085
22086 test_808() {
22087         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22088                 skip "Need MDS version at least 2.11.55"
22089
22090         # Registration step
22091         changelog_register || error "changelog_register failed"
22092
22093         touch $DIR/$tfile || error "touch $tfile failed"
22094         check_som_nologged
22095
22096         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
22097                 error "write $tfile failed"
22098         check_som_nologged
22099
22100         $TRUNCATE $DIR/$tfile 1234
22101         check_som_nologged
22102
22103         $TRUNCATE $DIR/$tfile 1048576
22104         check_som_nologged
22105
22106         # Deregistration step
22107         changelog_deregister || error "changelog_deregister failed"
22108 }
22109 run_test 808 "Check trusted.som xattr not logged in Changelogs"
22110
22111 check_som_nodata()
22112 {
22113         $LFS getsom $1
22114         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
22115 }
22116
22117 test_809() {
22118         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22119                 skip "Need MDS version at least 2.11.56"
22120
22121         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
22122                 error "failed to create DoM-only file $DIR/$tfile"
22123         touch $DIR/$tfile || error "touch $tfile failed"
22124         check_som_nodata $DIR/$tfile
22125
22126         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
22127                 error "write $tfile failed"
22128         check_som_nodata $DIR/$tfile
22129
22130         $TRUNCATE $DIR/$tfile 1234
22131         check_som_nodata $DIR/$tfile
22132
22133         $TRUNCATE $DIR/$tfile 4097
22134         check_som_nodata $DIR/$file
22135 }
22136 run_test 809 "Verify no SOM xattr store for DoM-only files"
22137
22138 test_810() {
22139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22140         $GSS && skip_env "could not run with gss"
22141
22142         set_checksums 1
22143         stack_trap "set_checksums $ORIG_CSUM" EXIT
22144         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
22145
22146         local csum
22147         local before
22148         local after
22149         for csum in $CKSUM_TYPES; do
22150                 #define OBD_FAIL_OSC_NO_GRANT   0x411
22151                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
22152                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
22153                         eval set -- $i
22154                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
22155                         before=$(md5sum $DIR/$tfile)
22156                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
22157                         after=$(md5sum $DIR/$tfile)
22158                         [ "$before" == "$after" ] ||
22159                                 error "$csum: $before != $after bs=$1 seek=$2"
22160                 done
22161         done
22162 }
22163 run_test 810 "partial page writes on ZFS (LU-11663)"
22164
22165 test_811() {
22166         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
22167                 skip "Need MDS version at least 2.11.56"
22168
22169         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
22170         do_facet mds1 $LCTL set_param fail_loc=0x165
22171         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
22172
22173         stop mds1
22174         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22175
22176         sleep 5
22177         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
22178                 error "MDD orphan cleanup thread not quit"
22179 }
22180 run_test 811 "orphan name stub can be cleaned up in startup"
22181
22182 test_812() {
22183         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
22184                 skip "OST < 2.12.51 doesn't support this fail_loc"
22185         [ "$SHARED_KEY" = true ] &&
22186                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22187
22188         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22189         # ensure ost1 is connected
22190         stat $DIR/$tfile >/dev/null || error "can't stat"
22191         wait_osc_import_state client ost1 FULL
22192         # no locks, no reqs to let the connection idle
22193         cancel_lru_locks osc
22194
22195         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
22196 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
22197         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
22198         wait_osc_import_state client ost1 CONNECTING
22199         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
22200
22201         stat $DIR/$tfile >/dev/null || error "can't stat file"
22202 }
22203 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
22204
22205 test_813() {
22206         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
22207         [ -z "$file_heat_sav" ] && skip "no file heat support"
22208
22209         local readsample
22210         local writesample
22211         local readbyte
22212         local writebyte
22213         local readsample1
22214         local writesample1
22215         local readbyte1
22216         local writebyte1
22217
22218         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
22219         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
22220
22221         $LCTL set_param -n llite.*.file_heat=1
22222         echo "Turn on file heat"
22223         echo "Period second: $period_second, Decay percentage: $decay_pct"
22224
22225         echo "QQQQ" > $DIR/$tfile
22226         echo "QQQQ" > $DIR/$tfile
22227         echo "QQQQ" > $DIR/$tfile
22228         cat $DIR/$tfile > /dev/null
22229         cat $DIR/$tfile > /dev/null
22230         cat $DIR/$tfile > /dev/null
22231         cat $DIR/$tfile > /dev/null
22232
22233         local out=$($LFS heat_get $DIR/$tfile)
22234
22235         $LFS heat_get $DIR/$tfile
22236         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22237         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22238         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22239         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22240
22241         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
22242         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
22243         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
22244         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
22245
22246         sleep $((period_second + 3))
22247         echo "Sleep $((period_second + 3)) seconds..."
22248         # The recursion formula to calculate the heat of the file f is as
22249         # follow:
22250         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
22251         # Where Hi is the heat value in the period between time points i*I and
22252         # (i+1)*I; Ci is the access count in the period; the symbol P refers
22253         # to the weight of Ci.
22254         out=$($LFS heat_get $DIR/$tfile)
22255         $LFS heat_get $DIR/$tfile
22256         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22257         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22258         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22259         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22260
22261         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
22262                 error "read sample ($readsample) is wrong"
22263         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
22264                 error "write sample ($writesample) is wrong"
22265         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
22266                 error "read bytes ($readbyte) is wrong"
22267         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
22268                 error "write bytes ($writebyte) is wrong"
22269
22270         echo "QQQQ" > $DIR/$tfile
22271         echo "QQQQ" > $DIR/$tfile
22272         echo "QQQQ" > $DIR/$tfile
22273         cat $DIR/$tfile > /dev/null
22274         cat $DIR/$tfile > /dev/null
22275         cat $DIR/$tfile > /dev/null
22276         cat $DIR/$tfile > /dev/null
22277
22278         sleep $((period_second + 3))
22279         echo "Sleep $((period_second + 3)) seconds..."
22280
22281         out=$($LFS heat_get $DIR/$tfile)
22282         $LFS heat_get $DIR/$tfile
22283         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22284         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22285         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22286         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22287
22288         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
22289                 4 * $decay_pct) / 100") -eq 1 ] ||
22290                 error "read sample ($readsample1) is wrong"
22291         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
22292                 3 * $decay_pct) / 100") -eq 1 ] ||
22293                 error "write sample ($writesample1) is wrong"
22294         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
22295                 20 * $decay_pct) / 100") -eq 1 ] ||
22296                 error "read bytes ($readbyte1) is wrong"
22297         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
22298                 15 * $decay_pct) / 100") -eq 1 ] ||
22299                 error "write bytes ($writebyte1) is wrong"
22300
22301         echo "Turn off file heat for the file $DIR/$tfile"
22302         $LFS heat_set -o $DIR/$tfile
22303
22304         echo "QQQQ" > $DIR/$tfile
22305         echo "QQQQ" > $DIR/$tfile
22306         echo "QQQQ" > $DIR/$tfile
22307         cat $DIR/$tfile > /dev/null
22308         cat $DIR/$tfile > /dev/null
22309         cat $DIR/$tfile > /dev/null
22310         cat $DIR/$tfile > /dev/null
22311
22312         out=$($LFS heat_get $DIR/$tfile)
22313         $LFS heat_get $DIR/$tfile
22314         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22315         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22316         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22317         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22318
22319         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22320         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22321         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22322         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22323
22324         echo "Trun on file heat for the file $DIR/$tfile"
22325         $LFS heat_set -O $DIR/$tfile
22326
22327         echo "QQQQ" > $DIR/$tfile
22328         echo "QQQQ" > $DIR/$tfile
22329         echo "QQQQ" > $DIR/$tfile
22330         cat $DIR/$tfile > /dev/null
22331         cat $DIR/$tfile > /dev/null
22332         cat $DIR/$tfile > /dev/null
22333         cat $DIR/$tfile > /dev/null
22334
22335         out=$($LFS heat_get $DIR/$tfile)
22336         $LFS heat_get $DIR/$tfile
22337         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22338         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22339         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22340         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22341
22342         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
22343         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
22344         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
22345         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
22346
22347         $LFS heat_set -c $DIR/$tfile
22348         $LCTL set_param -n llite.*.file_heat=0
22349         echo "Turn off file heat support for the Lustre filesystem"
22350
22351         echo "QQQQ" > $DIR/$tfile
22352         echo "QQQQ" > $DIR/$tfile
22353         echo "QQQQ" > $DIR/$tfile
22354         cat $DIR/$tfile > /dev/null
22355         cat $DIR/$tfile > /dev/null
22356         cat $DIR/$tfile > /dev/null
22357         cat $DIR/$tfile > /dev/null
22358
22359         out=$($LFS heat_get $DIR/$tfile)
22360         $LFS heat_get $DIR/$tfile
22361         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22362         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22363         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22364         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22365
22366         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22367         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22368         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22369         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22370
22371         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
22372         rm -f $DIR/$tfile
22373 }
22374 run_test 813 "File heat verfication"
22375
22376 test_814()
22377 {
22378         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
22379         echo -n y >> $DIR/$tfile
22380         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
22381         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
22382 }
22383 run_test 814 "sparse cp works as expected (LU-12361)"
22384
22385 test_815()
22386 {
22387         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
22388         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
22389 }
22390 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
22391
22392 test_816() {
22393         [ "$SHARED_KEY" = true ] &&
22394                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22395
22396         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22397         # ensure ost1 is connected
22398         stat $DIR/$tfile >/dev/null || error "can't stat"
22399         wait_osc_import_state client ost1 FULL
22400         # no locks, no reqs to let the connection idle
22401         cancel_lru_locks osc
22402         lru_resize_disable osc
22403         local before
22404         local now
22405         before=$($LCTL get_param -n \
22406                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22407
22408         wait_osc_import_state client ost1 IDLE
22409         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
22410         now=$($LCTL get_param -n \
22411               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22412         [ $before == $now ] || error "lru_size changed $before != $now"
22413 }
22414 run_test 816 "do not reset lru_resize on idle reconnect"
22415
22416 cleanup_817() {
22417         umount $tmpdir
22418         exportfs -u localhost:$DIR/nfsexp
22419         rm -rf $DIR/nfsexp
22420 }
22421
22422 test_817() {
22423         systemctl restart nfs-server.service || skip "failed to restart nfsd"
22424
22425         mkdir -p $DIR/nfsexp
22426         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
22427                 error "failed to export nfs"
22428
22429         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
22430         stack_trap cleanup_817 EXIT
22431
22432         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
22433                 error "failed to mount nfs to $tmpdir"
22434
22435         cp /bin/true $tmpdir
22436         $DIR/nfsexp/true || error "failed to execute 'true' command"
22437 }
22438 run_test 817 "nfsd won't cache write lock for exec file"
22439
22440 test_818() {
22441         mkdir $DIR/$tdir
22442         $LFS setstripe -c1 -i0 $DIR/$tfile
22443         $LFS setstripe -c1 -i1 $DIR/$tfile
22444         stop $SINGLEMDS
22445         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
22446         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
22447         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
22448                 error "start $SINGLEMDS failed"
22449         rm -rf $DIR/$tdir
22450 }
22451 run_test 818 "unlink with failed llog"
22452
22453 test_819a() {
22454         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22455         cancel_lru_locks osc
22456         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22457         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22458         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
22459         rm -f $TDIR/$tfile
22460 }
22461 run_test 819a "too big niobuf in read"
22462
22463 test_819b() {
22464         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22465         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22466         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22467         cancel_lru_locks osc
22468         sleep 1
22469         rm -f $TDIR/$tfile
22470 }
22471 run_test 819b "too big niobuf in write"
22472
22473 #
22474 # tests that do cleanup/setup should be run at the end
22475 #
22476
22477 test_900() {
22478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22479         local ls
22480
22481         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
22482         $LCTL set_param fail_loc=0x903
22483
22484         cancel_lru_locks MGC
22485
22486         FAIL_ON_ERROR=true cleanup
22487         FAIL_ON_ERROR=true setup
22488 }
22489 run_test 900 "umount should not race with any mgc requeue thread"
22490
22491 complete $SECONDS
22492 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
22493 check_and_cleanup_lustre
22494 if [ "$I_MOUNTED" != "yes" ]; then
22495         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
22496 fi
22497 exit_status