Whamcloud - gitweb
LU-12842 utils: llog_print with snapshot name
[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         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2472           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2473                 skip27D+=" -s 32,33"
2474         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2475                 skip27D+=" -s 34"
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         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2616                 skip "Need MDS version newer than 2.12.52"
2617         local pool=$TESTNAME
2618         local ostrange="1 1 1"
2619
2620         save_layout_restore_at_exit $MOUNT
2621         $LFS setstripe -c 2 -i 0 $MOUNT
2622         pool_add $pool || error "pool_add failed"
2623         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2624         test_mkdir $DIR/$tdir
2625         $LFS setstripe -p $pool $DIR/$tdir
2626         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2627         $LFS getstripe $DIR/$tdir/$tfile
2628 }
2629 run_test 27I "check that root dir striping does not break parent dir one"
2630
2631 test_27J() {
2632         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
2633                 skip "Need MDS version newer than 2.12.51"
2634
2635         test_mkdir $DIR/$tdir
2636         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2637         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2638
2639         # create foreign file (raw way)
2640         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2641                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2642
2643         # verify foreign file (raw way)
2644         parse_foreign_file -f $DIR/$tdir/$tfile |
2645                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2646                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2647         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2648                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2649         parse_foreign_file -f $DIR/$tdir/$tfile |
2650                 grep "lov_foreign_size: 73" ||
2651                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2652         parse_foreign_file -f $DIR/$tdir/$tfile |
2653                 grep "lov_foreign_type: 1" ||
2654                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2655         parse_foreign_file -f $DIR/$tdir/$tfile |
2656                 grep "lov_foreign_flags: 0x0000DA08" ||
2657                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2658         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2659                 grep "lov_foreign_value: 0x" |
2660                 sed -e 's/lov_foreign_value: 0x//')
2661         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2662         [[ $lov = ${lov2// /} ]] ||
2663                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2664
2665         # create foreign file (lfs + API)
2666         $LFS setstripe --foreign=daos --flags 0xda08 \
2667                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2668                 error "$DIR/$tdir/${tfile}2: create failed"
2669
2670         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2671                 grep "lfm_magic:.*0x0BD70BD0" ||
2672                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2673         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2674         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2675                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2676         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2677                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2678         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2679                 grep "lfm_flags:.*0x0000DA08" ||
2680                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2681         $LFS getstripe $DIR/$tdir/${tfile}2 |
2682                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2683                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2684
2685         # modify striping should fail
2686         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2687                 error "$DIR/$tdir/$tfile: setstripe should fail"
2688         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2689                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2690
2691         # R/W should fail
2692         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2693         cat $DIR/$tdir/${tfile}2 &&
2694                 error "$DIR/$tdir/${tfile}2: read should fail"
2695         cat /etc/passwd > $DIR/$tdir/$tfile &&
2696                 error "$DIR/$tdir/$tfile: write should fail"
2697         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2698                 error "$DIR/$tdir/${tfile}2: write should fail"
2699
2700         # chmod should work
2701         chmod 222 $DIR/$tdir/$tfile ||
2702                 error "$DIR/$tdir/$tfile: chmod failed"
2703         chmod 222 $DIR/$tdir/${tfile}2 ||
2704                 error "$DIR/$tdir/${tfile}2: chmod failed"
2705
2706         # chown should work
2707         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2708                 error "$DIR/$tdir/$tfile: chown failed"
2709         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2710                 error "$DIR/$tdir/${tfile}2: chown failed"
2711
2712         # rename should work
2713         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2714                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2715         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2716                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2717
2718         #remove foreign file
2719         rm $DIR/$tdir/${tfile}.new ||
2720                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2721         rm $DIR/$tdir/${tfile}2.new ||
2722                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2723 }
2724 run_test 27J "basic ops on file with foreign LOV"
2725
2726 test_27K() {
2727         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
2728                 skip "Need MDS version newer than 2.12.49"
2729
2730         test_mkdir $DIR/$tdir
2731         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2732         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2733
2734         # create foreign dir (raw way)
2735         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2736                 error "create_foreign_dir FAILED"
2737
2738         # verify foreign dir (raw way)
2739         parse_foreign_dir -d $DIR/$tdir/$tdir |
2740                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2741                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2742         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2743                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2744         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2745                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2746         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2747                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2748         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2749                 grep "lmv_foreign_value: 0x" |
2750                 sed 's/lmv_foreign_value: 0x//')
2751         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2752                 sed 's/ //g')
2753         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2754
2755         # create foreign dir (lfs + API)
2756         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2757                 $DIR/$tdir/${tdir}2 ||
2758                 error "$DIR/$tdir/${tdir}2: create failed"
2759
2760         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2761                 grep "lfm_magic:.*0x0CD50CD0" ||
2762                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2763         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2764         # - sizeof(lfm_type) - sizeof(lfm_flags)
2765         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2766                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2767         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2768                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2769         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2770                 grep "lfm_flags:.*0x0000DA05" ||
2771                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2772         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2773                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2774                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2775
2776         # file create in dir should fail
2777         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2778         touch $DIR/$tdir/${tdir}2/$tfile &&
2779                 "$DIR/${tdir}2: file create should fail"
2780
2781         # chmod should work
2782         chmod 777 $DIR/$tdir/$tdir ||
2783                 error "$DIR/$tdir: chmod failed"
2784         chmod 777 $DIR/$tdir/${tdir}2 ||
2785                 error "$DIR/${tdir}2: chmod failed"
2786
2787         # chown should work
2788         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2789                 error "$DIR/$tdir: chown failed"
2790         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2791                 error "$DIR/${tdir}2: chown failed"
2792
2793         # rename should work
2794         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2795                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2796         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2797                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2798
2799         #remove foreign dir
2800         rmdir $DIR/$tdir/${tdir}.new ||
2801                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2802         rmdir $DIR/$tdir/${tdir}2.new ||
2803                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2804 }
2805 run_test 27K "basic ops on dir with foreign LMV"
2806
2807 test_27L() {
2808         remote_mds_nodsh && skip "remote MDS with nodsh"
2809
2810         local POOL=${POOL:-$TESTNAME}
2811
2812         pool_add $POOL || error "pool_add failed"
2813
2814         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2815                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2816                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2817 }
2818 run_test 27L "lfs pool_list gives correct pool name"
2819
2820 test_27M() {
2821         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2822                 skip "Need MDS version >= than 2.12.57"
2823         remote_mds_nodsh && skip "remote MDS with nodsh"
2824         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2825
2826         test_mkdir $DIR/$tdir
2827
2828         # Set default striping on directory
2829         $LFS setstripe -C 4 $DIR/$tdir
2830
2831         echo 1 > $DIR/$tdir/${tfile}.1
2832         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2833         local setcount=4
2834         [ $count -eq $setcount ] ||
2835                 error "(1) stripe count $count, should be $setcount"
2836
2837         # Capture existing append_stripe_count setting for restore
2838         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2839         local mdts=$(comma_list $(mdts_nodes))
2840         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2841
2842         local appendcount=$orig_count
2843         echo 1 >> $DIR/$tdir/${tfile}.2_append
2844         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2845         [ $count -eq $appendcount ] ||
2846                 error "(2)stripe count $count, should be $appendcount for append"
2847
2848         # Disable O_APPEND striping, verify it works
2849         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2850
2851         # Should now get the default striping, which is 4
2852         setcount=4
2853         echo 1 >> $DIR/$tdir/${tfile}.3_append
2854         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2855         [ $count -eq $setcount ] ||
2856                 error "(3) stripe count $count, should be $setcount"
2857
2858         # Try changing the stripe count for append files
2859         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2860
2861         # Append striping is now 2 (directory default is still 4)
2862         appendcount=2
2863         echo 1 >> $DIR/$tdir/${tfile}.4_append
2864         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2865         [ $count -eq $appendcount ] ||
2866                 error "(4) stripe count $count, should be $appendcount for append"
2867
2868         # Test append stripe count of -1
2869         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2870         appendcount=$OSTCOUNT
2871         echo 1 >> $DIR/$tdir/${tfile}.5
2872         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2873         [ $count -eq $appendcount ] ||
2874                 error "(5) stripe count $count, should be $appendcount for append"
2875
2876         # Set append striping back to default of 1
2877         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2878
2879         # Try a new default striping, PFL + DOM
2880         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2881
2882         # Create normal DOM file, DOM returns stripe count == 0
2883         setcount=0
2884         touch $DIR/$tdir/${tfile}.6
2885         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2886         [ $count -eq $setcount ] ||
2887                 error "(6) stripe count $count, should be $setcount"
2888
2889         # Show
2890         appendcount=1
2891         echo 1 >> $DIR/$tdir/${tfile}.7_append
2892         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2893         [ $count -eq $appendcount ] ||
2894                 error "(7) stripe count $count, should be $appendcount for append"
2895
2896         # Clean up DOM layout
2897         $LFS setstripe -d $DIR/$tdir
2898
2899         # Now test that append striping works when layout is from root
2900         $LFS setstripe -c 2 $MOUNT
2901         # Make a special directory for this
2902         mkdir $DIR/${tdir}/${tdir}.2
2903         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2904
2905         # Verify for normal file
2906         setcount=2
2907         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2908         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2909         [ $count -eq $setcount ] ||
2910                 error "(8) stripe count $count, should be $setcount"
2911
2912         appendcount=1
2913         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2914         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2915         [ $count -eq $appendcount ] ||
2916                 error "(9) stripe count $count, should be $appendcount for append"
2917
2918         # Now test O_APPEND striping with pools
2919         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2920         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2921
2922         # Create the pool
2923         pool_add $TESTNAME || error "pool creation failed"
2924         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2925
2926         echo 1 >> $DIR/$tdir/${tfile}.10_append
2927
2928         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2929         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2930
2931         # Check that count is still correct
2932         appendcount=1
2933         echo 1 >> $DIR/$tdir/${tfile}.11_append
2934         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2935         [ $count -eq $appendcount ] ||
2936                 error "(11) stripe count $count, should be $appendcount for append"
2937
2938         # Disable O_APPEND stripe count, verify pool works separately
2939         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2940
2941         echo 1 >> $DIR/$tdir/${tfile}.12_append
2942
2943         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
2944         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
2945
2946         # Remove pool setting, verify it's not applied
2947         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
2948
2949         echo 1 >> $DIR/$tdir/${tfile}.13_append
2950
2951         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
2952         [ "$pool" = "" ] || error "(13) pool found: $pool"
2953 }
2954 run_test 27M "test O_APPEND striping"
2955
2956 test_27N() {
2957         combined_mgs_mds && skip "needs separate MGS/MDT"
2958
2959         pool_add $TESTNAME || error "pool_add failed"
2960         do_facet mgs "$LCTL pool_list $FSNAME" |
2961                 grep -Fx "${FSNAME}.${TESTNAME}" ||
2962                 error "lctl pool_list on MGS failed"
2963 }
2964 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
2965
2966 # createtest also checks that device nodes are created and
2967 # then visible correctly (#2091)
2968 test_28() { # bug 2091
2969         test_mkdir $DIR/d28
2970         $CREATETEST $DIR/d28/ct || error "createtest failed"
2971 }
2972 run_test 28 "create/mknod/mkdir with bad file types ============"
2973
2974 test_29() {
2975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2976
2977         sync; sleep 1; sync # flush out any dirty pages from previous tests
2978         cancel_lru_locks
2979         test_mkdir $DIR/d29
2980         touch $DIR/d29/foo
2981         log 'first d29'
2982         ls -l $DIR/d29
2983
2984         declare -i LOCKCOUNTORIG=0
2985         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2986                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2987         done
2988         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2989
2990         declare -i LOCKUNUSEDCOUNTORIG=0
2991         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2992                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2993         done
2994
2995         log 'second d29'
2996         ls -l $DIR/d29
2997         log 'done'
2998
2999         declare -i LOCKCOUNTCURRENT=0
3000         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3001                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3002         done
3003
3004         declare -i LOCKUNUSEDCOUNTCURRENT=0
3005         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3006                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3007         done
3008
3009         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3010                 $LCTL set_param -n ldlm.dump_namespaces ""
3011                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3012                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3013                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3014                 return 2
3015         fi
3016         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3017                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3018                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3019                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3020                 return 3
3021         fi
3022 }
3023 run_test 29 "IT_GETATTR regression  ============================"
3024
3025 test_30a() { # was test_30
3026         cp $(which ls) $DIR || cp /bin/ls $DIR
3027         $DIR/ls / || error "Can't execute binary from lustre"
3028         rm $DIR/ls
3029 }
3030 run_test 30a "execute binary from Lustre (execve) =============="
3031
3032 test_30b() {
3033         cp `which ls` $DIR || cp /bin/ls $DIR
3034         chmod go+rx $DIR/ls
3035         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3036         rm $DIR/ls
3037 }
3038 run_test 30b "execute binary from Lustre as non-root ==========="
3039
3040 test_30c() { # b=22376
3041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3042
3043         cp `which ls` $DIR || cp /bin/ls $DIR
3044         chmod a-rw $DIR/ls
3045         cancel_lru_locks mdc
3046         cancel_lru_locks osc
3047         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3048         rm -f $DIR/ls
3049 }
3050 run_test 30c "execute binary from Lustre without read perms ===="
3051
3052 test_31a() {
3053         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3054         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3055 }
3056 run_test 31a "open-unlink file =================================="
3057
3058 test_31b() {
3059         touch $DIR/f31 || error "touch $DIR/f31 failed"
3060         ln $DIR/f31 $DIR/f31b || error "ln failed"
3061         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3062         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3063 }
3064 run_test 31b "unlink file with multiple links while open ======="
3065
3066 test_31c() {
3067         touch $DIR/f31 || error "touch $DIR/f31 failed"
3068         ln $DIR/f31 $DIR/f31c || error "ln failed"
3069         multiop_bg_pause $DIR/f31 O_uc ||
3070                 error "multiop_bg_pause for $DIR/f31 failed"
3071         MULTIPID=$!
3072         $MULTIOP $DIR/f31c Ouc
3073         kill -USR1 $MULTIPID
3074         wait $MULTIPID
3075 }
3076 run_test 31c "open-unlink file with multiple links ============="
3077
3078 test_31d() {
3079         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3080         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3081 }
3082 run_test 31d "remove of open directory ========================="
3083
3084 test_31e() { # bug 2904
3085         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3086 }
3087 run_test 31e "remove of open non-empty directory ==============="
3088
3089 test_31f() { # bug 4554
3090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3091
3092         set -vx
3093         test_mkdir $DIR/d31f
3094         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3095         cp /etc/hosts $DIR/d31f
3096         ls -l $DIR/d31f
3097         $LFS getstripe $DIR/d31f/hosts
3098         multiop_bg_pause $DIR/d31f D_c || return 1
3099         MULTIPID=$!
3100
3101         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3102         test_mkdir $DIR/d31f
3103         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3104         cp /etc/hosts $DIR/d31f
3105         ls -l $DIR/d31f
3106         $LFS getstripe $DIR/d31f/hosts
3107         multiop_bg_pause $DIR/d31f D_c || return 1
3108         MULTIPID2=$!
3109
3110         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3111         wait $MULTIPID || error "first opendir $MULTIPID failed"
3112
3113         sleep 6
3114
3115         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3116         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3117         set +vx
3118 }
3119 run_test 31f "remove of open directory with open-unlink file ==="
3120
3121 test_31g() {
3122         echo "-- cross directory link --"
3123         test_mkdir -c1 $DIR/${tdir}ga
3124         test_mkdir -c1 $DIR/${tdir}gb
3125         touch $DIR/${tdir}ga/f
3126         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3127         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3128         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3129         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3130         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3131 }
3132 run_test 31g "cross directory link==============="
3133
3134 test_31h() {
3135         echo "-- cross directory link --"
3136         test_mkdir -c1 $DIR/${tdir}
3137         test_mkdir -c1 $DIR/${tdir}/dir
3138         touch $DIR/${tdir}/f
3139         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3140         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3141         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3142         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3143         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3144 }
3145 run_test 31h "cross directory link under child==============="
3146
3147 test_31i() {
3148         echo "-- cross directory link --"
3149         test_mkdir -c1 $DIR/$tdir
3150         test_mkdir -c1 $DIR/$tdir/dir
3151         touch $DIR/$tdir/dir/f
3152         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3153         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3154         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3155         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3156         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3157 }
3158 run_test 31i "cross directory link under parent==============="
3159
3160 test_31j() {
3161         test_mkdir -c1 -p $DIR/$tdir
3162         test_mkdir -c1 -p $DIR/$tdir/dir1
3163         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3164         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3165         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3166         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3167         return 0
3168 }
3169 run_test 31j "link for directory==============="
3170
3171 test_31k() {
3172         test_mkdir -c1 -p $DIR/$tdir
3173         touch $DIR/$tdir/s
3174         touch $DIR/$tdir/exist
3175         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3176         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3177         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3178         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3179         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3180         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3181         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3182         return 0
3183 }
3184 run_test 31k "link to file: the same, non-existing, dir==============="
3185
3186 test_31m() {
3187         mkdir $DIR/d31m
3188         touch $DIR/d31m/s
3189         mkdir $DIR/d31m2
3190         touch $DIR/d31m2/exist
3191         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3192         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3193         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3194         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3195         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3196         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3197         return 0
3198 }
3199 run_test 31m "link to file: the same, non-existing, dir==============="
3200
3201 test_31n() {
3202         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3203         nlink=$(stat --format=%h $DIR/$tfile)
3204         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3205         local fd=$(free_fd)
3206         local cmd="exec $fd<$DIR/$tfile"
3207         eval $cmd
3208         cmd="exec $fd<&-"
3209         trap "eval $cmd" EXIT
3210         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3211         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3212         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3213         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3214         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3215         eval $cmd
3216 }
3217 run_test 31n "check link count of unlinked file"
3218
3219 link_one() {
3220         local tempfile=$(mktemp $1_XXXXXX)
3221         mlink $tempfile $1 2> /dev/null &&
3222                 echo "$BASHPID: link $tempfile to $1 succeeded"
3223         munlink $tempfile
3224 }
3225
3226 test_31o() { # LU-2901
3227         test_mkdir $DIR/$tdir
3228         for LOOP in $(seq 100); do
3229                 rm -f $DIR/$tdir/$tfile*
3230                 for THREAD in $(seq 8); do
3231                         link_one $DIR/$tdir/$tfile.$LOOP &
3232                 done
3233                 wait
3234                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3235                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3236                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3237                         break || true
3238         done
3239 }
3240 run_test 31o "duplicate hard links with same filename"
3241
3242 test_31p() {
3243         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3244
3245         test_mkdir $DIR/$tdir
3246         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3247         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3248
3249         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3250                 error "open unlink test1 failed"
3251         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3252                 error "open unlink test2 failed"
3253
3254         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3255                 error "test1 still exists"
3256         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3257                 error "test2 still exists"
3258 }
3259 run_test 31p "remove of open striped directory"
3260
3261 cleanup_test32_mount() {
3262         local rc=0
3263         trap 0
3264         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3265         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3266         losetup -d $loopdev || true
3267         rm -rf $DIR/$tdir
3268         return $rc
3269 }
3270
3271 test_32a() {
3272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3273
3274         echo "== more mountpoints and symlinks ================="
3275         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3276         trap cleanup_test32_mount EXIT
3277         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3278         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3279                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3280         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3281                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3282         cleanup_test32_mount
3283 }
3284 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3285
3286 test_32b() {
3287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3288
3289         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3290         trap cleanup_test32_mount EXIT
3291         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3292         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3293                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3294         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3295                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3296         cleanup_test32_mount
3297 }
3298 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3299
3300 test_32c() {
3301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3302
3303         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3304         trap cleanup_test32_mount EXIT
3305         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3306         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3307                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3308         test_mkdir -p $DIR/$tdir/d2/test_dir
3309         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3310                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3311         cleanup_test32_mount
3312 }
3313 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3314
3315 test_32d() {
3316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3317
3318         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3319         trap cleanup_test32_mount EXIT
3320         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3321         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3322                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3323         test_mkdir -p $DIR/$tdir/d2/test_dir
3324         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3325                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3326         cleanup_test32_mount
3327 }
3328 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3329
3330 test_32e() {
3331         rm -fr $DIR/$tdir
3332         test_mkdir -p $DIR/$tdir/tmp
3333         local tmp_dir=$DIR/$tdir/tmp
3334         ln -s $DIR/$tdir $tmp_dir/symlink11
3335         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3336         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3337         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3338 }
3339 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3340
3341 test_32f() {
3342         rm -fr $DIR/$tdir
3343         test_mkdir -p $DIR/$tdir/tmp
3344         local tmp_dir=$DIR/$tdir/tmp
3345         ln -s $DIR/$tdir $tmp_dir/symlink11
3346         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3347         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3348         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3349 }
3350 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3351
3352 test_32g() {
3353         local tmp_dir=$DIR/$tdir/tmp
3354         test_mkdir -p $tmp_dir
3355         test_mkdir $DIR/${tdir}2
3356         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3357         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3358         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3359         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3360         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3361         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3362 }
3363 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3364
3365 test_32h() {
3366         rm -fr $DIR/$tdir $DIR/${tdir}2
3367         tmp_dir=$DIR/$tdir/tmp
3368         test_mkdir -p $tmp_dir
3369         test_mkdir $DIR/${tdir}2
3370         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3371         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3372         ls $tmp_dir/symlink12 || error "listing symlink12"
3373         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3374 }
3375 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3376
3377 test_32i() {
3378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3379
3380         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3381         trap cleanup_test32_mount EXIT
3382         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3383         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3384                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3385         touch $DIR/$tdir/test_file
3386         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3387                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3388         cleanup_test32_mount
3389 }
3390 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3391
3392 test_32j() {
3393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3394
3395         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3396         trap cleanup_test32_mount EXIT
3397         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3398         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3399                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3400         touch $DIR/$tdir/test_file
3401         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3402                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3403         cleanup_test32_mount
3404 }
3405 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3406
3407 test_32k() {
3408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3409
3410         rm -fr $DIR/$tdir
3411         trap cleanup_test32_mount EXIT
3412         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3413         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3414                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3415         test_mkdir -p $DIR/$tdir/d2
3416         touch $DIR/$tdir/d2/test_file || error "touch failed"
3417         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3418                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3419         cleanup_test32_mount
3420 }
3421 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3422
3423 test_32l() {
3424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3425
3426         rm -fr $DIR/$tdir
3427         trap cleanup_test32_mount EXIT
3428         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3429         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3430                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3431         test_mkdir -p $DIR/$tdir/d2
3432         touch $DIR/$tdir/d2/test_file || error "touch failed"
3433         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3434                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3435         cleanup_test32_mount
3436 }
3437 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3438
3439 test_32m() {
3440         rm -fr $DIR/d32m
3441         test_mkdir -p $DIR/d32m/tmp
3442         TMP_DIR=$DIR/d32m/tmp
3443         ln -s $DIR $TMP_DIR/symlink11
3444         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3445         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3446                 error "symlink11 not a link"
3447         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3448                 error "symlink01 not a link"
3449 }
3450 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3451
3452 test_32n() {
3453         rm -fr $DIR/d32n
3454         test_mkdir -p $DIR/d32n/tmp
3455         TMP_DIR=$DIR/d32n/tmp
3456         ln -s $DIR $TMP_DIR/symlink11
3457         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3458         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3459         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3460 }
3461 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3462
3463 test_32o() {
3464         touch $DIR/$tfile
3465         test_mkdir -p $DIR/d32o/tmp
3466         TMP_DIR=$DIR/d32o/tmp
3467         ln -s $DIR/$tfile $TMP_DIR/symlink12
3468         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3469         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3470                 error "symlink12 not a link"
3471         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3472         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3473                 error "$DIR/d32o/tmp/symlink12 not file type"
3474         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3475                 error "$DIR/d32o/symlink02 not file type"
3476 }
3477 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3478
3479 test_32p() {
3480         log 32p_1
3481         rm -fr $DIR/d32p
3482         log 32p_2
3483         rm -f $DIR/$tfile
3484         log 32p_3
3485         touch $DIR/$tfile
3486         log 32p_4
3487         test_mkdir -p $DIR/d32p/tmp
3488         log 32p_5
3489         TMP_DIR=$DIR/d32p/tmp
3490         log 32p_6
3491         ln -s $DIR/$tfile $TMP_DIR/symlink12
3492         log 32p_7
3493         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3494         log 32p_8
3495         cat $DIR/d32p/tmp/symlink12 ||
3496                 error "Can't open $DIR/d32p/tmp/symlink12"
3497         log 32p_9
3498         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3499         log 32p_10
3500 }
3501 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3502
3503 test_32q() {
3504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3505
3506         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3507         trap cleanup_test32_mount EXIT
3508         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3509         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3510         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3511                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3512         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3513         cleanup_test32_mount
3514 }
3515 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3516
3517 test_32r() {
3518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3519
3520         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3521         trap cleanup_test32_mount EXIT
3522         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3523         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3524         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3525                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3526         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3527         cleanup_test32_mount
3528 }
3529 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3530
3531 test_33aa() {
3532         rm -f $DIR/$tfile
3533         touch $DIR/$tfile
3534         chmod 444 $DIR/$tfile
3535         chown $RUNAS_ID $DIR/$tfile
3536         log 33_1
3537         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3538         log 33_2
3539 }
3540 run_test 33aa "write file with mode 444 (should return error)"
3541
3542 test_33a() {
3543         rm -fr $DIR/$tdir
3544         test_mkdir $DIR/$tdir
3545         chown $RUNAS_ID $DIR/$tdir
3546         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3547                 error "$RUNAS create $tdir/$tfile failed"
3548         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3549                 error "open RDWR" || true
3550 }
3551 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3552
3553 test_33b() {
3554         rm -fr $DIR/$tdir
3555         test_mkdir $DIR/$tdir
3556         chown $RUNAS_ID $DIR/$tdir
3557         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3558 }
3559 run_test 33b "test open file with malformed flags (No panic)"
3560
3561 test_33c() {
3562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3563         remote_ost_nodsh && skip "remote OST with nodsh"
3564
3565         local ostnum
3566         local ostname
3567         local write_bytes
3568         local all_zeros
3569
3570         all_zeros=:
3571         rm -fr $DIR/$tdir
3572         test_mkdir $DIR/$tdir
3573         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3574
3575         sync
3576         for ostnum in $(seq $OSTCOUNT); do
3577                 # test-framework's OST numbering is one-based, while Lustre's
3578                 # is zero-based
3579                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3580                 # Parsing llobdstat's output sucks; we could grep the /proc
3581                 # path, but that's likely to not be as portable as using the
3582                 # llobdstat utility.  So we parse lctl output instead.
3583                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3584                         obdfilter/$ostname/stats |
3585                         awk '/^write_bytes/ {print $7}' )
3586                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3587                 if (( ${write_bytes:-0} > 0 ))
3588                 then
3589                         all_zeros=false
3590                         break;
3591                 fi
3592         done
3593
3594         $all_zeros || return 0
3595
3596         # Write four bytes
3597         echo foo > $DIR/$tdir/bar
3598         # Really write them
3599         sync
3600
3601         # Total up write_bytes after writing.  We'd better find non-zeros.
3602         for ostnum in $(seq $OSTCOUNT); do
3603                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3604                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3605                         obdfilter/$ostname/stats |
3606                         awk '/^write_bytes/ {print $7}' )
3607                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3608                 if (( ${write_bytes:-0} > 0 ))
3609                 then
3610                         all_zeros=false
3611                         break;
3612                 fi
3613         done
3614
3615         if $all_zeros
3616         then
3617                 for ostnum in $(seq $OSTCOUNT); do
3618                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3619                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3620                         do_facet ost$ostnum lctl get_param -n \
3621                                 obdfilter/$ostname/stats
3622                 done
3623                 error "OST not keeping write_bytes stats (b22312)"
3624         fi
3625 }
3626 run_test 33c "test llobdstat and write_bytes"
3627
3628 test_33d() {
3629         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3631
3632         local MDTIDX=1
3633         local remote_dir=$DIR/$tdir/remote_dir
3634
3635         test_mkdir $DIR/$tdir
3636         $LFS mkdir -i $MDTIDX $remote_dir ||
3637                 error "create remote directory failed"
3638
3639         touch $remote_dir/$tfile
3640         chmod 444 $remote_dir/$tfile
3641         chown $RUNAS_ID $remote_dir/$tfile
3642
3643         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3644
3645         chown $RUNAS_ID $remote_dir
3646         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3647                                         error "create" || true
3648         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3649                                     error "open RDWR" || true
3650         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3651 }
3652 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3653
3654 test_33e() {
3655         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3656
3657         mkdir $DIR/$tdir
3658
3659         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3660         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3661         mkdir $DIR/$tdir/local_dir
3662
3663         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3664         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3665         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3666
3667         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3668                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3669
3670         rmdir $DIR/$tdir/* || error "rmdir failed"
3671
3672         umask 777
3673         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3674         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3675         mkdir $DIR/$tdir/local_dir
3676
3677         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3678         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3679         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3680
3681         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3682                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3683
3684         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3685
3686         umask 000
3687         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3688         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3689         mkdir $DIR/$tdir/local_dir
3690
3691         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3692         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3693         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3694
3695         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3696                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3697 }
3698 run_test 33e "mkdir and striped directory should have same mode"
3699
3700 cleanup_33f() {
3701         trap 0
3702         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3703 }
3704
3705 test_33f() {
3706         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3707         remote_mds_nodsh && skip "remote MDS with nodsh"
3708
3709         mkdir $DIR/$tdir
3710         chmod go+rwx $DIR/$tdir
3711         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3712         trap cleanup_33f EXIT
3713
3714         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3715                 error "cannot create striped directory"
3716
3717         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3718                 error "cannot create files in striped directory"
3719
3720         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3721                 error "cannot remove files in striped directory"
3722
3723         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3724                 error "cannot remove striped directory"
3725
3726         cleanup_33f
3727 }
3728 run_test 33f "nonroot user can create, access, and remove a striped directory"
3729
3730 test_33g() {
3731         mkdir -p $DIR/$tdir/dir2
3732
3733         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3734         echo $err
3735         [[ $err =~ "exists" ]] || error "Not exists error"
3736 }
3737 run_test 33g "nonroot user create already existing root created file"
3738
3739 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3740 test_34a() {
3741         rm -f $DIR/f34
3742         $MCREATE $DIR/f34 || error "mcreate failed"
3743         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3744                 error "getstripe failed"
3745         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3746         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3747                 error "getstripe failed"
3748         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3749                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3750 }
3751 run_test 34a "truncate file that has not been opened ==========="
3752
3753 test_34b() {
3754         [ ! -f $DIR/f34 ] && test_34a
3755         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3756                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3757         $OPENFILE -f O_RDONLY $DIR/f34
3758         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3759                 error "getstripe failed"
3760         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3761                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3762 }
3763 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3764
3765 test_34c() {
3766         [ ! -f $DIR/f34 ] && test_34a
3767         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3768                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3769         $OPENFILE -f O_RDWR $DIR/f34
3770         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3771                 error "$LFS getstripe failed"
3772         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3773                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3774 }
3775 run_test 34c "O_RDWR opening file-with-size works =============="
3776
3777 test_34d() {
3778         [ ! -f $DIR/f34 ] && test_34a
3779         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3780                 error "dd failed"
3781         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3782                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3783         rm $DIR/f34
3784 }
3785 run_test 34d "write to sparse file ============================="
3786
3787 test_34e() {
3788         rm -f $DIR/f34e
3789         $MCREATE $DIR/f34e || error "mcreate failed"
3790         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3791         $CHECKSTAT -s 1000 $DIR/f34e ||
3792                 error "Size of $DIR/f34e not equal to 1000 bytes"
3793         $OPENFILE -f O_RDWR $DIR/f34e
3794         $CHECKSTAT -s 1000 $DIR/f34e ||
3795                 error "Size of $DIR/f34e not equal to 1000 bytes"
3796 }
3797 run_test 34e "create objects, some with size and some without =="
3798
3799 test_34f() { # bug 6242, 6243
3800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3801
3802         SIZE34F=48000
3803         rm -f $DIR/f34f
3804         $MCREATE $DIR/f34f || error "mcreate failed"
3805         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3806         dd if=$DIR/f34f of=$TMP/f34f
3807         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3808         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3809         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3810         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3811         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3812 }
3813 run_test 34f "read from a file with no objects until EOF ======="
3814
3815 test_34g() {
3816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3817
3818         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3819                 error "dd failed"
3820         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3821         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3822                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3823         cancel_lru_locks osc
3824         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3825                 error "wrong size after lock cancel"
3826
3827         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3828         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3829                 error "expanding truncate failed"
3830         cancel_lru_locks osc
3831         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3832                 error "wrong expanded size after lock cancel"
3833 }
3834 run_test 34g "truncate long file ==============================="
3835
3836 test_34h() {
3837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3838
3839         local gid=10
3840         local sz=1000
3841
3842         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3843         sync # Flush the cache so that multiop below does not block on cache
3844              # flush when getting the group lock
3845         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3846         MULTIPID=$!
3847
3848         # Since just timed wait is not good enough, let's do a sync write
3849         # that way we are sure enough time for a roundtrip + processing
3850         # passed + 2 seconds of extra margin.
3851         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3852         rm $DIR/${tfile}-1
3853         sleep 2
3854
3855         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3856                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3857                 kill -9 $MULTIPID
3858         fi
3859         wait $MULTIPID
3860         local nsz=`stat -c %s $DIR/$tfile`
3861         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3862 }
3863 run_test 34h "ftruncate file under grouplock should not block"
3864
3865 test_35a() {
3866         cp /bin/sh $DIR/f35a
3867         chmod 444 $DIR/f35a
3868         chown $RUNAS_ID $DIR/f35a
3869         $RUNAS $DIR/f35a && error || true
3870         rm $DIR/f35a
3871 }
3872 run_test 35a "exec file with mode 444 (should return and not leak)"
3873
3874 test_36a() {
3875         rm -f $DIR/f36
3876         utime $DIR/f36 || error "utime failed for MDS"
3877 }
3878 run_test 36a "MDS utime check (mknod, utime)"
3879
3880 test_36b() {
3881         echo "" > $DIR/f36
3882         utime $DIR/f36 || error "utime failed for OST"
3883 }
3884 run_test 36b "OST utime check (open, utime)"
3885
3886 test_36c() {
3887         rm -f $DIR/d36/f36
3888         test_mkdir $DIR/d36
3889         chown $RUNAS_ID $DIR/d36
3890         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3891 }
3892 run_test 36c "non-root MDS utime check (mknod, utime)"
3893
3894 test_36d() {
3895         [ ! -d $DIR/d36 ] && test_36c
3896         echo "" > $DIR/d36/f36
3897         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3898 }
3899 run_test 36d "non-root OST utime check (open, utime)"
3900
3901 test_36e() {
3902         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3903
3904         test_mkdir $DIR/$tdir
3905         touch $DIR/$tdir/$tfile
3906         $RUNAS utime $DIR/$tdir/$tfile &&
3907                 error "utime worked, expected failure" || true
3908 }
3909 run_test 36e "utime on non-owned file (should return error)"
3910
3911 subr_36fh() {
3912         local fl="$1"
3913         local LANG_SAVE=$LANG
3914         local LC_LANG_SAVE=$LC_LANG
3915         export LANG=C LC_LANG=C # for date language
3916
3917         DATESTR="Dec 20  2000"
3918         test_mkdir $DIR/$tdir
3919         lctl set_param fail_loc=$fl
3920         date; date +%s
3921         cp /etc/hosts $DIR/$tdir/$tfile
3922         sync & # write RPC generated with "current" inode timestamp, but delayed
3923         sleep 1
3924         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3925         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3926         cancel_lru_locks $OSC
3927         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3928         date; date +%s
3929         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3930                 echo "BEFORE: $LS_BEFORE" && \
3931                 echo "AFTER : $LS_AFTER" && \
3932                 echo "WANT  : $DATESTR" && \
3933                 error "$DIR/$tdir/$tfile timestamps changed" || true
3934
3935         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3936 }
3937
3938 test_36f() {
3939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3940
3941         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3942         subr_36fh "0x80000214"
3943 }
3944 run_test 36f "utime on file racing with OST BRW write =========="
3945
3946 test_36g() {
3947         remote_ost_nodsh && skip "remote OST with nodsh"
3948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3949         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3950                 skip "Need MDS version at least 2.12.51"
3951
3952         local fmd_max_age
3953         local fmd
3954         local facet="ost1"
3955         local tgt="obdfilter"
3956
3957         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3958
3959         test_mkdir $DIR/$tdir
3960         fmd_max_age=$(do_facet $facet \
3961                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3962                 head -n 1")
3963
3964         echo "FMD max age: ${fmd_max_age}s"
3965         touch $DIR/$tdir/$tfile
3966         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3967                 gawk '{cnt=cnt+$1}  END{print cnt}')
3968         echo "FMD before: $fmd"
3969         [[ $fmd == 0 ]] &&
3970                 error "FMD wasn't create by touch"
3971         sleep $((fmd_max_age + 12))
3972         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3973                 gawk '{cnt=cnt+$1}  END{print cnt}')
3974         echo "FMD after: $fmd"
3975         [[ $fmd == 0 ]] ||
3976                 error "FMD wasn't expired by ping"
3977 }
3978 run_test 36g "FMD cache expiry ====================="
3979
3980 test_36h() {
3981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3982
3983         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3984         subr_36fh "0x80000227"
3985 }
3986 run_test 36h "utime on file racing with OST BRW write =========="
3987
3988 test_36i() {
3989         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3990
3991         test_mkdir $DIR/$tdir
3992         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3993
3994         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3995         local new_mtime=$((mtime + 200))
3996
3997         #change Modify time of striped dir
3998         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3999                         error "change mtime failed"
4000
4001         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4002
4003         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4004 }
4005 run_test 36i "change mtime on striped directory"
4006
4007 # test_37 - duplicate with tests 32q 32r
4008
4009 test_38() {
4010         local file=$DIR/$tfile
4011         touch $file
4012         openfile -f O_DIRECTORY $file
4013         local RC=$?
4014         local ENOTDIR=20
4015         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4016         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4017 }
4018 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4019
4020 test_39a() { # was test_39
4021         touch $DIR/$tfile
4022         touch $DIR/${tfile}2
4023 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4024 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4025 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4026         sleep 2
4027         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4028         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4029                 echo "mtime"
4030                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4031                 echo "atime"
4032                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4033                 echo "ctime"
4034                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4035                 error "O_TRUNC didn't change timestamps"
4036         fi
4037 }
4038 run_test 39a "mtime changed on create"
4039
4040 test_39b() {
4041         test_mkdir -c1 $DIR/$tdir
4042         cp -p /etc/passwd $DIR/$tdir/fopen
4043         cp -p /etc/passwd $DIR/$tdir/flink
4044         cp -p /etc/passwd $DIR/$tdir/funlink
4045         cp -p /etc/passwd $DIR/$tdir/frename
4046         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4047
4048         sleep 1
4049         echo "aaaaaa" >> $DIR/$tdir/fopen
4050         echo "aaaaaa" >> $DIR/$tdir/flink
4051         echo "aaaaaa" >> $DIR/$tdir/funlink
4052         echo "aaaaaa" >> $DIR/$tdir/frename
4053
4054         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4055         local link_new=`stat -c %Y $DIR/$tdir/flink`
4056         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4057         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4058
4059         cat $DIR/$tdir/fopen > /dev/null
4060         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4061         rm -f $DIR/$tdir/funlink2
4062         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4063
4064         for (( i=0; i < 2; i++ )) ; do
4065                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4066                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4067                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4068                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4069
4070                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4071                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4072                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4073                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4074
4075                 cancel_lru_locks $OSC
4076                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4077         done
4078 }
4079 run_test 39b "mtime change on open, link, unlink, rename  ======"
4080
4081 # this should be set to past
4082 TEST_39_MTIME=`date -d "1 year ago" +%s`
4083
4084 # bug 11063
4085 test_39c() {
4086         touch $DIR1/$tfile
4087         sleep 2
4088         local mtime0=`stat -c %Y $DIR1/$tfile`
4089
4090         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4091         local mtime1=`stat -c %Y $DIR1/$tfile`
4092         [ "$mtime1" = $TEST_39_MTIME ] || \
4093                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4094
4095         local d1=`date +%s`
4096         echo hello >> $DIR1/$tfile
4097         local d2=`date +%s`
4098         local mtime2=`stat -c %Y $DIR1/$tfile`
4099         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4100                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4101
4102         mv $DIR1/$tfile $DIR1/$tfile-1
4103
4104         for (( i=0; i < 2; i++ )) ; do
4105                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4106                 [ "$mtime2" = "$mtime3" ] || \
4107                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4108
4109                 cancel_lru_locks $OSC
4110                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4111         done
4112 }
4113 run_test 39c "mtime change on rename ==========================="
4114
4115 # bug 21114
4116 test_39d() {
4117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4118
4119         touch $DIR1/$tfile
4120         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4121
4122         for (( i=0; i < 2; i++ )) ; do
4123                 local mtime=`stat -c %Y $DIR1/$tfile`
4124                 [ $mtime = $TEST_39_MTIME ] || \
4125                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4126
4127                 cancel_lru_locks $OSC
4128                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4129         done
4130 }
4131 run_test 39d "create, utime, stat =============================="
4132
4133 # bug 21114
4134 test_39e() {
4135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4136
4137         touch $DIR1/$tfile
4138         local mtime1=`stat -c %Y $DIR1/$tfile`
4139
4140         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4141
4142         for (( i=0; i < 2; i++ )) ; do
4143                 local mtime2=`stat -c %Y $DIR1/$tfile`
4144                 [ $mtime2 = $TEST_39_MTIME ] || \
4145                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4146
4147                 cancel_lru_locks $OSC
4148                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4149         done
4150 }
4151 run_test 39e "create, stat, utime, stat ========================"
4152
4153 # bug 21114
4154 test_39f() {
4155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4156
4157         touch $DIR1/$tfile
4158         mtime1=`stat -c %Y $DIR1/$tfile`
4159
4160         sleep 2
4161         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4162
4163         for (( i=0; i < 2; i++ )) ; do
4164                 local mtime2=`stat -c %Y $DIR1/$tfile`
4165                 [ $mtime2 = $TEST_39_MTIME ] || \
4166                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4167
4168                 cancel_lru_locks $OSC
4169                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4170         done
4171 }
4172 run_test 39f "create, stat, sleep, utime, stat ================="
4173
4174 # bug 11063
4175 test_39g() {
4176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4177
4178         echo hello >> $DIR1/$tfile
4179         local mtime1=`stat -c %Y $DIR1/$tfile`
4180
4181         sleep 2
4182         chmod o+r $DIR1/$tfile
4183
4184         for (( i=0; i < 2; i++ )) ; do
4185                 local mtime2=`stat -c %Y $DIR1/$tfile`
4186                 [ "$mtime1" = "$mtime2" ] || \
4187                         error "lost mtime: $mtime2, should be $mtime1"
4188
4189                 cancel_lru_locks $OSC
4190                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4191         done
4192 }
4193 run_test 39g "write, chmod, stat ==============================="
4194
4195 # bug 11063
4196 test_39h() {
4197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4198
4199         touch $DIR1/$tfile
4200         sleep 1
4201
4202         local d1=`date`
4203         echo hello >> $DIR1/$tfile
4204         local mtime1=`stat -c %Y $DIR1/$tfile`
4205
4206         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4207         local d2=`date`
4208         if [ "$d1" != "$d2" ]; then
4209                 echo "write and touch not within one second"
4210         else
4211                 for (( i=0; i < 2; i++ )) ; do
4212                         local mtime2=`stat -c %Y $DIR1/$tfile`
4213                         [ "$mtime2" = $TEST_39_MTIME ] || \
4214                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4215
4216                         cancel_lru_locks $OSC
4217                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4218                 done
4219         fi
4220 }
4221 run_test 39h "write, utime within one second, stat ============="
4222
4223 test_39i() {
4224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4225
4226         touch $DIR1/$tfile
4227         sleep 1
4228
4229         echo hello >> $DIR1/$tfile
4230         local mtime1=`stat -c %Y $DIR1/$tfile`
4231
4232         mv $DIR1/$tfile $DIR1/$tfile-1
4233
4234         for (( i=0; i < 2; i++ )) ; do
4235                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4236
4237                 [ "$mtime1" = "$mtime2" ] || \
4238                         error "lost mtime: $mtime2, should be $mtime1"
4239
4240                 cancel_lru_locks $OSC
4241                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4242         done
4243 }
4244 run_test 39i "write, rename, stat =============================="
4245
4246 test_39j() {
4247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4248
4249         start_full_debug_logging
4250         touch $DIR1/$tfile
4251         sleep 1
4252
4253         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4254         lctl set_param fail_loc=0x80000412
4255         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4256                 error "multiop failed"
4257         local multipid=$!
4258         local mtime1=`stat -c %Y $DIR1/$tfile`
4259
4260         mv $DIR1/$tfile $DIR1/$tfile-1
4261
4262         kill -USR1 $multipid
4263         wait $multipid || error "multiop close failed"
4264
4265         for (( i=0; i < 2; i++ )) ; do
4266                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4267                 [ "$mtime1" = "$mtime2" ] ||
4268                         error "mtime is lost on close: $mtime2, " \
4269                               "should be $mtime1"
4270
4271                 cancel_lru_locks
4272                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4273         done
4274         lctl set_param fail_loc=0
4275         stop_full_debug_logging
4276 }
4277 run_test 39j "write, rename, close, stat ======================="
4278
4279 test_39k() {
4280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4281
4282         touch $DIR1/$tfile
4283         sleep 1
4284
4285         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4286         local multipid=$!
4287         local mtime1=`stat -c %Y $DIR1/$tfile`
4288
4289         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4290
4291         kill -USR1 $multipid
4292         wait $multipid || error "multiop close failed"
4293
4294         for (( i=0; i < 2; i++ )) ; do
4295                 local mtime2=`stat -c %Y $DIR1/$tfile`
4296
4297                 [ "$mtime2" = $TEST_39_MTIME ] || \
4298                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4299
4300                 cancel_lru_locks
4301                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4302         done
4303 }
4304 run_test 39k "write, utime, close, stat ========================"
4305
4306 # this should be set to future
4307 TEST_39_ATIME=`date -d "1 year" +%s`
4308
4309 test_39l() {
4310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4311         remote_mds_nodsh && skip "remote MDS with nodsh"
4312
4313         local atime_diff=$(do_facet $SINGLEMDS \
4314                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4315         rm -rf $DIR/$tdir
4316         mkdir -p $DIR/$tdir
4317
4318         # test setting directory atime to future
4319         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4320         local atime=$(stat -c %X $DIR/$tdir)
4321         [ "$atime" = $TEST_39_ATIME ] ||
4322                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4323
4324         # test setting directory atime from future to now
4325         local now=$(date +%s)
4326         touch -a -d @$now $DIR/$tdir
4327
4328         atime=$(stat -c %X $DIR/$tdir)
4329         [ "$atime" -eq "$now"  ] ||
4330                 error "atime is not updated from future: $atime, $now"
4331
4332         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4333         sleep 3
4334
4335         # test setting directory atime when now > dir atime + atime_diff
4336         local d1=$(date +%s)
4337         ls $DIR/$tdir
4338         local d2=$(date +%s)
4339         cancel_lru_locks mdc
4340         atime=$(stat -c %X $DIR/$tdir)
4341         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4342                 error "atime is not updated  : $atime, should be $d2"
4343
4344         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4345         sleep 3
4346
4347         # test not setting directory atime when now < dir atime + atime_diff
4348         ls $DIR/$tdir
4349         cancel_lru_locks mdc
4350         atime=$(stat -c %X $DIR/$tdir)
4351         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4352                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4353
4354         do_facet $SINGLEMDS \
4355                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4356 }
4357 run_test 39l "directory atime update ==========================="
4358
4359 test_39m() {
4360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4361
4362         touch $DIR1/$tfile
4363         sleep 2
4364         local far_past_mtime=$(date -d "May 29 1953" +%s)
4365         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4366
4367         touch -m -d @$far_past_mtime $DIR1/$tfile
4368         touch -a -d @$far_past_atime $DIR1/$tfile
4369
4370         for (( i=0; i < 2; i++ )) ; do
4371                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4372                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4373                         error "atime or mtime set incorrectly"
4374
4375                 cancel_lru_locks $OSC
4376                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4377         done
4378 }
4379 run_test 39m "test atime and mtime before 1970"
4380
4381 test_39n() { # LU-3832
4382         remote_mds_nodsh && skip "remote MDS with nodsh"
4383
4384         local atime_diff=$(do_facet $SINGLEMDS \
4385                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4386         local atime0
4387         local atime1
4388         local atime2
4389
4390         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4391
4392         rm -rf $DIR/$tfile
4393         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4394         atime0=$(stat -c %X $DIR/$tfile)
4395
4396         sleep 5
4397         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4398         atime1=$(stat -c %X $DIR/$tfile)
4399
4400         sleep 5
4401         cancel_lru_locks mdc
4402         cancel_lru_locks osc
4403         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4404         atime2=$(stat -c %X $DIR/$tfile)
4405
4406         do_facet $SINGLEMDS \
4407                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4408
4409         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4410         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4411 }
4412 run_test 39n "check that O_NOATIME is honored"
4413
4414 test_39o() {
4415         TESTDIR=$DIR/$tdir/$tfile
4416         [ -e $TESTDIR ] && rm -rf $TESTDIR
4417         mkdir -p $TESTDIR
4418         cd $TESTDIR
4419         links1=2
4420         ls
4421         mkdir a b
4422         ls
4423         links2=$(stat -c %h .)
4424         [ $(($links1 + 2)) != $links2 ] &&
4425                 error "wrong links count $(($links1 + 2)) != $links2"
4426         rmdir b
4427         links3=$(stat -c %h .)
4428         [ $(($links1 + 1)) != $links3 ] &&
4429                 error "wrong links count $links1 != $links3"
4430         return 0
4431 }
4432 run_test 39o "directory cached attributes updated after create"
4433
4434 test_39p() {
4435         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4436
4437         local MDTIDX=1
4438         TESTDIR=$DIR/$tdir/$tdir
4439         [ -e $TESTDIR ] && rm -rf $TESTDIR
4440         test_mkdir -p $TESTDIR
4441         cd $TESTDIR
4442         links1=2
4443         ls
4444         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4445         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4446         ls
4447         links2=$(stat -c %h .)
4448         [ $(($links1 + 2)) != $links2 ] &&
4449                 error "wrong links count $(($links1 + 2)) != $links2"
4450         rmdir remote_dir2
4451         links3=$(stat -c %h .)
4452         [ $(($links1 + 1)) != $links3 ] &&
4453                 error "wrong links count $links1 != $links3"
4454         return 0
4455 }
4456 run_test 39p "remote directory cached attributes updated after create ========"
4457
4458
4459 test_39q() { # LU-8041
4460         local testdir=$DIR/$tdir
4461         mkdir -p $testdir
4462         multiop_bg_pause $testdir D_c || error "multiop failed"
4463         local multipid=$!
4464         cancel_lru_locks mdc
4465         kill -USR1 $multipid
4466         local atime=$(stat -c %X $testdir)
4467         [ "$atime" -ne 0 ] || error "atime is zero"
4468 }
4469 run_test 39q "close won't zero out atime"
4470
4471 test_40() {
4472         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4473         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4474                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4475         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4476                 error "$tfile is not 4096 bytes in size"
4477 }
4478 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4479
4480 test_41() {
4481         # bug 1553
4482         small_write $DIR/f41 18
4483 }
4484 run_test 41 "test small file write + fstat ====================="
4485
4486 count_ost_writes() {
4487         lctl get_param -n ${OSC}.*.stats |
4488                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4489                         END { printf("%0.0f", writes) }'
4490 }
4491
4492 # decent default
4493 WRITEBACK_SAVE=500
4494 DIRTY_RATIO_SAVE=40
4495 MAX_DIRTY_RATIO=50
4496 BG_DIRTY_RATIO_SAVE=10
4497 MAX_BG_DIRTY_RATIO=25
4498
4499 start_writeback() {
4500         trap 0
4501         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4502         # dirty_ratio, dirty_background_ratio
4503         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4504                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4505                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4506                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4507         else
4508                 # if file not here, we are a 2.4 kernel
4509                 kill -CONT `pidof kupdated`
4510         fi
4511 }
4512
4513 stop_writeback() {
4514         # setup the trap first, so someone cannot exit the test at the
4515         # exact wrong time and mess up a machine
4516         trap start_writeback EXIT
4517         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4518         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4519                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4520                 sysctl -w vm.dirty_writeback_centisecs=0
4521                 sysctl -w vm.dirty_writeback_centisecs=0
4522                 # save and increase /proc/sys/vm/dirty_ratio
4523                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4524                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4525                 # save and increase /proc/sys/vm/dirty_background_ratio
4526                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4527                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4528         else
4529                 # if file not here, we are a 2.4 kernel
4530                 kill -STOP `pidof kupdated`
4531         fi
4532 }
4533
4534 # ensure that all stripes have some grant before we test client-side cache
4535 setup_test42() {
4536         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4537                 dd if=/dev/zero of=$i bs=4k count=1
4538                 rm $i
4539         done
4540 }
4541
4542 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4543 # file truncation, and file removal.
4544 test_42a() {
4545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4546
4547         setup_test42
4548         cancel_lru_locks $OSC
4549         stop_writeback
4550         sync; sleep 1; sync # just to be safe
4551         BEFOREWRITES=`count_ost_writes`
4552         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4553         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4554         AFTERWRITES=`count_ost_writes`
4555         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4556                 error "$BEFOREWRITES < $AFTERWRITES"
4557         start_writeback
4558 }
4559 run_test 42a "ensure that we don't flush on close"
4560
4561 test_42b() {
4562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4563
4564         setup_test42
4565         cancel_lru_locks $OSC
4566         stop_writeback
4567         sync
4568         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4569         BEFOREWRITES=$(count_ost_writes)
4570         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4571         AFTERWRITES=$(count_ost_writes)
4572         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4573                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4574         fi
4575         BEFOREWRITES=$(count_ost_writes)
4576         sync || error "sync: $?"
4577         AFTERWRITES=$(count_ost_writes)
4578         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4579                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4580         fi
4581         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4582         start_writeback
4583         return 0
4584 }
4585 run_test 42b "test destroy of file with cached dirty data ======"
4586
4587 # if these tests just want to test the effect of truncation,
4588 # they have to be very careful.  consider:
4589 # - the first open gets a {0,EOF}PR lock
4590 # - the first write conflicts and gets a {0, count-1}PW
4591 # - the rest of the writes are under {count,EOF}PW
4592 # - the open for truncate tries to match a {0,EOF}PR
4593 #   for the filesize and cancels the PWs.
4594 # any number of fixes (don't get {0,EOF} on open, match
4595 # composite locks, do smarter file size management) fix
4596 # this, but for now we want these tests to verify that
4597 # the cancellation with truncate intent works, so we
4598 # start the file with a full-file pw lock to match against
4599 # until the truncate.
4600 trunc_test() {
4601         test=$1
4602         file=$DIR/$test
4603         offset=$2
4604         cancel_lru_locks $OSC
4605         stop_writeback
4606         # prime the file with 0,EOF PW to match
4607         touch $file
4608         $TRUNCATE $file 0
4609         sync; sync
4610         # now the real test..
4611         dd if=/dev/zero of=$file bs=1024 count=100
4612         BEFOREWRITES=`count_ost_writes`
4613         $TRUNCATE $file $offset
4614         cancel_lru_locks $OSC
4615         AFTERWRITES=`count_ost_writes`
4616         start_writeback
4617 }
4618
4619 test_42c() {
4620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4621
4622         trunc_test 42c 1024
4623         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4624                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4625         rm $file
4626 }
4627 run_test 42c "test partial truncate of file with cached dirty data"
4628
4629 test_42d() {
4630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4631
4632         trunc_test 42d 0
4633         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4634                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4635         rm $file
4636 }
4637 run_test 42d "test complete truncate of file with cached dirty data"
4638
4639 test_42e() { # bug22074
4640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4641
4642         local TDIR=$DIR/${tdir}e
4643         local pages=16 # hardcoded 16 pages, don't change it.
4644         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4645         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4646         local max_dirty_mb
4647         local warmup_files
4648
4649         test_mkdir $DIR/${tdir}e
4650         $LFS setstripe -c 1 $TDIR
4651         createmany -o $TDIR/f $files
4652
4653         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4654
4655         # we assume that with $OSTCOUNT files, at least one of them will
4656         # be allocated on OST0.
4657         warmup_files=$((OSTCOUNT * max_dirty_mb))
4658         createmany -o $TDIR/w $warmup_files
4659
4660         # write a large amount of data into one file and sync, to get good
4661         # avail_grant number from OST.
4662         for ((i=0; i<$warmup_files; i++)); do
4663                 idx=$($LFS getstripe -i $TDIR/w$i)
4664                 [ $idx -ne 0 ] && continue
4665                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4666                 break
4667         done
4668         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4669         sync
4670         $LCTL get_param $proc_osc0/cur_dirty_bytes
4671         $LCTL get_param $proc_osc0/cur_grant_bytes
4672
4673         # create as much dirty pages as we can while not to trigger the actual
4674         # RPCs directly. but depends on the env, VFS may trigger flush during this
4675         # period, hopefully we are good.
4676         for ((i=0; i<$warmup_files; i++)); do
4677                 idx=$($LFS getstripe -i $TDIR/w$i)
4678                 [ $idx -ne 0 ] && continue
4679                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4680         done
4681         $LCTL get_param $proc_osc0/cur_dirty_bytes
4682         $LCTL get_param $proc_osc0/cur_grant_bytes
4683
4684         # perform the real test
4685         $LCTL set_param $proc_osc0/rpc_stats 0
4686         for ((;i<$files; i++)); do
4687                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4688                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4689         done
4690         sync
4691         $LCTL get_param $proc_osc0/rpc_stats
4692
4693         local percent=0
4694         local have_ppr=false
4695         $LCTL get_param $proc_osc0/rpc_stats |
4696                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4697                         # skip lines until we are at the RPC histogram data
4698                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4699                         $have_ppr || continue
4700
4701                         # we only want the percent stat for < 16 pages
4702                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4703
4704                         percent=$((percent + WPCT))
4705                         if [[ $percent -gt 15 ]]; then
4706                                 error "less than 16-pages write RPCs" \
4707                                       "$percent% > 15%"
4708                                 break
4709                         fi
4710                 done
4711         rm -rf $TDIR
4712 }
4713 run_test 42e "verify sub-RPC writes are not done synchronously"
4714
4715 test_43A() { # was test_43
4716         test_mkdir $DIR/$tdir
4717         cp -p /bin/ls $DIR/$tdir/$tfile
4718         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4719         pid=$!
4720         # give multiop a chance to open
4721         sleep 1
4722
4723         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4724         kill -USR1 $pid
4725 }
4726 run_test 43A "execution of file opened for write should return -ETXTBSY"
4727
4728 test_43a() {
4729         test_mkdir $DIR/$tdir
4730         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4731         $DIR/$tdir/sleep 60 &
4732         SLEEP_PID=$!
4733         # Make sure exec of $tdir/sleep wins race with truncate
4734         sleep 1
4735         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4736         kill $SLEEP_PID
4737 }
4738 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4739
4740 test_43b() {
4741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4742
4743         test_mkdir $DIR/$tdir
4744         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4745         $DIR/$tdir/sleep 60 &
4746         SLEEP_PID=$!
4747         # Make sure exec of $tdir/sleep wins race with truncate
4748         sleep 1
4749         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4750         kill $SLEEP_PID
4751 }
4752 run_test 43b "truncate of file being executed should return -ETXTBSY"
4753
4754 test_43c() {
4755         local testdir="$DIR/$tdir"
4756         test_mkdir $testdir
4757         cp $SHELL $testdir/
4758         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4759                 ( cd $testdir && md5sum -c )
4760 }
4761 run_test 43c "md5sum of copy into lustre"
4762
4763 test_44A() { # was test_44
4764         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4765
4766         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4767         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4768 }
4769 run_test 44A "zero length read from a sparse stripe"
4770
4771 test_44a() {
4772         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4773                 awk '{ print $2 }')
4774         [ -z "$nstripe" ] && skip "can't get stripe info"
4775         [[ $nstripe -gt $OSTCOUNT ]] &&
4776                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4777
4778         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4779                 awk '{ print $2 }')
4780         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4781                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4782                         awk '{ print $2 }')
4783         fi
4784
4785         OFFSETS="0 $((stride/2)) $((stride-1))"
4786         for offset in $OFFSETS; do
4787                 for i in $(seq 0 $((nstripe-1))); do
4788                         local GLOBALOFFSETS=""
4789                         # size in Bytes
4790                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4791                         local myfn=$DIR/d44a-$size
4792                         echo "--------writing $myfn at $size"
4793                         ll_sparseness_write $myfn $size ||
4794                                 error "ll_sparseness_write"
4795                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4796                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4797                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4798
4799                         for j in $(seq 0 $((nstripe-1))); do
4800                                 # size in Bytes
4801                                 size=$((((j + $nstripe )*$stride + $offset)))
4802                                 ll_sparseness_write $myfn $size ||
4803                                         error "ll_sparseness_write"
4804                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4805                         done
4806                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4807                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4808                         rm -f $myfn
4809                 done
4810         done
4811 }
4812 run_test 44a "test sparse pwrite ==============================="
4813
4814 dirty_osc_total() {
4815         tot=0
4816         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4817                 tot=$(($tot + $d))
4818         done
4819         echo $tot
4820 }
4821 do_dirty_record() {
4822         before=`dirty_osc_total`
4823         echo executing "\"$*\""
4824         eval $*
4825         after=`dirty_osc_total`
4826         echo before $before, after $after
4827 }
4828 test_45() {
4829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4830
4831         f="$DIR/f45"
4832         # Obtain grants from OST if it supports it
4833         echo blah > ${f}_grant
4834         stop_writeback
4835         sync
4836         do_dirty_record "echo blah > $f"
4837         [[ $before -eq $after ]] && error "write wasn't cached"
4838         do_dirty_record "> $f"
4839         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4840         do_dirty_record "echo blah > $f"
4841         [[ $before -eq $after ]] && error "write wasn't cached"
4842         do_dirty_record "sync"
4843         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4844         do_dirty_record "echo blah > $f"
4845         [[ $before -eq $after ]] && error "write wasn't cached"
4846         do_dirty_record "cancel_lru_locks osc"
4847         [[ $before -gt $after ]] ||
4848                 error "lock cancellation didn't lower dirty count"
4849         start_writeback
4850 }
4851 run_test 45 "osc io page accounting ============================"
4852
4853 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4854 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4855 # objects offset and an assert hit when an rpc was built with 1023's mapped
4856 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4857 test_46() {
4858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4859
4860         f="$DIR/f46"
4861         stop_writeback
4862         sync
4863         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4864         sync
4865         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4866         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4867         sync
4868         start_writeback
4869 }
4870 run_test 46 "dirtying a previously written page ================"
4871
4872 # test_47 is removed "Device nodes check" is moved to test_28
4873
4874 test_48a() { # bug 2399
4875         [ "$mds1_FSTYPE" = "zfs" ] &&
4876         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4877                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4878
4879         test_mkdir $DIR/$tdir
4880         cd $DIR/$tdir
4881         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4882         test_mkdir $DIR/$tdir
4883         touch foo || error "'touch foo' failed after recreating cwd"
4884         test_mkdir bar
4885         touch .foo || error "'touch .foo' failed after recreating cwd"
4886         test_mkdir .bar
4887         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4888         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4889         cd . || error "'cd .' failed after recreating cwd"
4890         mkdir . && error "'mkdir .' worked after recreating cwd"
4891         rmdir . && error "'rmdir .' worked after recreating cwd"
4892         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4893         cd .. || error "'cd ..' failed after recreating cwd"
4894 }
4895 run_test 48a "Access renamed working dir (should return errors)="
4896
4897 test_48b() { # bug 2399
4898         rm -rf $DIR/$tdir
4899         test_mkdir $DIR/$tdir
4900         cd $DIR/$tdir
4901         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4902         touch foo && error "'touch foo' worked after removing cwd"
4903         mkdir foo && error "'mkdir foo' worked after removing cwd"
4904         touch .foo && error "'touch .foo' worked after removing cwd"
4905         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4906         ls . > /dev/null && error "'ls .' worked after removing cwd"
4907         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4908         mkdir . && error "'mkdir .' worked after removing cwd"
4909         rmdir . && error "'rmdir .' worked after removing cwd"
4910         ln -s . foo && error "'ln -s .' worked after removing cwd"
4911         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4912 }
4913 run_test 48b "Access removed working dir (should return errors)="
4914
4915 test_48c() { # bug 2350
4916         #lctl set_param debug=-1
4917         #set -vx
4918         rm -rf $DIR/$tdir
4919         test_mkdir -p $DIR/$tdir/dir
4920         cd $DIR/$tdir/dir
4921         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4922         $TRACE touch foo && error "touch foo worked after removing cwd"
4923         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4924         touch .foo && error "touch .foo worked after removing cwd"
4925         mkdir .foo && error "mkdir .foo worked after removing cwd"
4926         $TRACE ls . && error "'ls .' worked after removing cwd"
4927         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4928         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4929         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4930         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4931         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4932 }
4933 run_test 48c "Access removed working subdir (should return errors)"
4934
4935 test_48d() { # bug 2350
4936         #lctl set_param debug=-1
4937         #set -vx
4938         rm -rf $DIR/$tdir
4939         test_mkdir -p $DIR/$tdir/dir
4940         cd $DIR/$tdir/dir
4941         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4942         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4943         $TRACE touch foo && error "'touch foo' worked after removing parent"
4944         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4945         touch .foo && error "'touch .foo' worked after removing parent"
4946         mkdir .foo && error "mkdir .foo worked after removing parent"
4947         $TRACE ls . && error "'ls .' worked after removing parent"
4948         $TRACE ls .. && error "'ls ..' worked after removing parent"
4949         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4950         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4951         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4952         true
4953 }
4954 run_test 48d "Access removed parent subdir (should return errors)"
4955
4956 test_48e() { # bug 4134
4957         #lctl set_param debug=-1
4958         #set -vx
4959         rm -rf $DIR/$tdir
4960         test_mkdir -p $DIR/$tdir/dir
4961         cd $DIR/$tdir/dir
4962         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4963         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4964         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4965         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4966         # On a buggy kernel addition of "touch foo" after cd .. will
4967         # produce kernel oops in lookup_hash_it
4968         touch ../foo && error "'cd ..' worked after recreate parent"
4969         cd $DIR
4970         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4971 }
4972 run_test 48e "Access to recreated parent subdir (should return errors)"
4973
4974 test_49() { # LU-1030
4975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4976         remote_ost_nodsh && skip "remote OST with nodsh"
4977
4978         # get ost1 size - lustre-OST0000
4979         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4980                 awk '{ print $4 }')
4981         # write 800M at maximum
4982         [[ $ost1_size -lt 2 ]] && ost1_size=2
4983         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4984
4985         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4986         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4987         local dd_pid=$!
4988
4989         # change max_pages_per_rpc while writing the file
4990         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4991         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4992         # loop until dd process exits
4993         while ps ax -opid | grep -wq $dd_pid; do
4994                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4995                 sleep $((RANDOM % 5 + 1))
4996         done
4997         # restore original max_pages_per_rpc
4998         $LCTL set_param $osc1_mppc=$orig_mppc
4999         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5000 }
5001 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5002
5003 test_50() {
5004         # bug 1485
5005         test_mkdir $DIR/$tdir
5006         cd $DIR/$tdir
5007         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5008 }
5009 run_test 50 "special situations: /proc symlinks  ==============="
5010
5011 test_51a() {    # was test_51
5012         # bug 1516 - create an empty entry right after ".." then split dir
5013         test_mkdir -c1 $DIR/$tdir
5014         touch $DIR/$tdir/foo
5015         $MCREATE $DIR/$tdir/bar
5016         rm $DIR/$tdir/foo
5017         createmany -m $DIR/$tdir/longfile 201
5018         FNUM=202
5019         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5020                 $MCREATE $DIR/$tdir/longfile$FNUM
5021                 FNUM=$(($FNUM + 1))
5022                 echo -n "+"
5023         done
5024         echo
5025         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5026 }
5027 run_test 51a "special situations: split htree with empty entry =="
5028
5029 cleanup_print_lfs_df () {
5030         trap 0
5031         $LFS df
5032         $LFS df -i
5033 }
5034
5035 test_51b() {
5036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5037
5038         local dir=$DIR/$tdir
5039         local nrdirs=$((65536 + 100))
5040
5041         # cleanup the directory
5042         rm -fr $dir
5043
5044         test_mkdir -c1 $dir
5045
5046         $LFS df
5047         $LFS df -i
5048         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5049         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5050         [[ $numfree -lt $nrdirs ]] &&
5051                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5052
5053         # need to check free space for the directories as well
5054         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5055         numfree=$(( blkfree / $(fs_inode_ksize) ))
5056         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5057
5058         trap cleanup_print_lfs_df EXIT
5059
5060         # create files
5061         createmany -d $dir/d $nrdirs || {
5062                 unlinkmany $dir/d $nrdirs
5063                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5064         }
5065
5066         # really created :
5067         nrdirs=$(ls -U $dir | wc -l)
5068
5069         # unlink all but 100 subdirectories, then check it still works
5070         local left=100
5071         local delete=$((nrdirs - left))
5072
5073         $LFS df
5074         $LFS df -i
5075
5076         # for ldiskfs the nlink count should be 1, but this is OSD specific
5077         # and so this is listed for informational purposes only
5078         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5079         unlinkmany -d $dir/d $delete ||
5080                 error "unlink of first $delete subdirs failed"
5081
5082         echo "nlink between: $(stat -c %h $dir)"
5083         local found=$(ls -U $dir | wc -l)
5084         [ $found -ne $left ] &&
5085                 error "can't find subdirs: found only $found, expected $left"
5086
5087         unlinkmany -d $dir/d $delete $left ||
5088                 error "unlink of second $left subdirs failed"
5089         # regardless of whether the backing filesystem tracks nlink accurately
5090         # or not, the nlink count shouldn't be more than "." and ".." here
5091         local after=$(stat -c %h $dir)
5092         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5093                 echo "nlink after: $after"
5094
5095         cleanup_print_lfs_df
5096 }
5097 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5098
5099 test_51d() {
5100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5101         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5102
5103         test_mkdir $DIR/$tdir
5104         createmany -o $DIR/$tdir/t- 1000
5105         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5106         for N in $(seq 0 $((OSTCOUNT - 1))); do
5107                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5108                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5109                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5110                         '($1 == '$N') { objs += 1 } \
5111                         END { printf("%0.0f", objs) }')
5112                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5113         done
5114         unlinkmany $DIR/$tdir/t- 1000
5115
5116         NLAST=0
5117         for N in $(seq 1 $((OSTCOUNT - 1))); do
5118                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5119                         error "OST $N has less objects vs OST $NLAST" \
5120                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5121                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5122                         error "OST $N has less objects vs OST $NLAST" \
5123                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5124
5125                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5126                         error "OST $N has less #0 objects vs OST $NLAST" \
5127                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5128                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5129                         error "OST $N has less #0 objects vs OST $NLAST" \
5130                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5131                 NLAST=$N
5132         done
5133         rm -f $TMP/$tfile
5134 }
5135 run_test 51d "check object distribution"
5136
5137 test_51e() {
5138         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5139                 skip_env "ldiskfs only test"
5140         fi
5141
5142         test_mkdir -c1 $DIR/$tdir
5143         test_mkdir -c1 $DIR/$tdir/d0
5144
5145         touch $DIR/$tdir/d0/foo
5146         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5147                 error "file exceed 65000 nlink limit!"
5148         unlinkmany $DIR/$tdir/d0/f- 65001
5149         return 0
5150 }
5151 run_test 51e "check file nlink limit"
5152
5153 test_51f() {
5154         test_mkdir $DIR/$tdir
5155
5156         local max=100000
5157         local ulimit_old=$(ulimit -n)
5158         local spare=20 # number of spare fd's for scripts/libraries, etc.
5159         local mdt=$($LFS getstripe -m $DIR/$tdir)
5160         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5161
5162         echo "MDT$mdt numfree=$numfree, max=$max"
5163         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5164         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5165                 while ! ulimit -n $((numfree + spare)); do
5166                         numfree=$((numfree * 3 / 4))
5167                 done
5168                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5169         else
5170                 echo "left ulimit at $ulimit_old"
5171         fi
5172
5173         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5174                 unlinkmany $DIR/$tdir/f $numfree
5175                 error "create+open $numfree files in $DIR/$tdir failed"
5176         }
5177         ulimit -n $ulimit_old
5178
5179         # if createmany exits at 120s there will be fewer than $numfree files
5180         unlinkmany $DIR/$tdir/f $numfree || true
5181 }
5182 run_test 51f "check many open files limit"
5183
5184 test_52a() {
5185         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5186         test_mkdir $DIR/$tdir
5187         touch $DIR/$tdir/foo
5188         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5189         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5190         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5191         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5192         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5193                                         error "link worked"
5194         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5195         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5196         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5197                                                      error "lsattr"
5198         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5199         cp -r $DIR/$tdir $TMP/
5200         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5201 }
5202 run_test 52a "append-only flag test (should return errors)"
5203
5204 test_52b() {
5205         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5206         test_mkdir $DIR/$tdir
5207         touch $DIR/$tdir/foo
5208         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5209         cat test > $DIR/$tdir/foo && error "cat test worked"
5210         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5211         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5212         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5213                                         error "link worked"
5214         echo foo >> $DIR/$tdir/foo && error "echo worked"
5215         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5216         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5217         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5218         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5219                                                         error "lsattr"
5220         chattr -i $DIR/$tdir/foo || error "chattr failed"
5221
5222         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5223 }
5224 run_test 52b "immutable flag test (should return errors) ======="
5225
5226 test_53() {
5227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5228         remote_mds_nodsh && skip "remote MDS with nodsh"
5229         remote_ost_nodsh && skip "remote OST with nodsh"
5230
5231         local param
5232         local param_seq
5233         local ostname
5234         local mds_last
5235         local mds_last_seq
5236         local ost_last
5237         local ost_last_seq
5238         local ost_last_id
5239         local ostnum
5240         local node
5241         local found=false
5242         local support_last_seq=true
5243
5244         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5245                 support_last_seq=false
5246
5247         # only test MDT0000
5248         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5249         local value
5250         for value in $(do_facet $SINGLEMDS \
5251                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5252                 param=$(echo ${value[0]} | cut -d "=" -f1)
5253                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5254
5255                 if $support_last_seq; then
5256                         param_seq=$(echo $param |
5257                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5258                         mds_last_seq=$(do_facet $SINGLEMDS \
5259                                        $LCTL get_param -n $param_seq)
5260                 fi
5261                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5262
5263                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5264                 node=$(facet_active_host ost$((ostnum+1)))
5265                 param="obdfilter.$ostname.last_id"
5266                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5267                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5268                         ost_last_id=$ost_last
5269
5270                         if $support_last_seq; then
5271                                 ost_last_id=$(echo $ost_last |
5272                                               awk -F':' '{print $2}' |
5273                                               sed -e "s/^0x//g")
5274                                 ost_last_seq=$(echo $ost_last |
5275                                                awk -F':' '{print $1}')
5276                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5277                         fi
5278
5279                         if [[ $ost_last_id != $mds_last ]]; then
5280                                 error "$ost_last_id != $mds_last"
5281                         else
5282                                 found=true
5283                                 break
5284                         fi
5285                 done
5286         done
5287         $found || error "can not match last_seq/last_id for $mdtosc"
5288         return 0
5289 }
5290 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5291
5292 test_54a() {
5293         perl -MSocket -e ';' || skip "no Socket perl module installed"
5294
5295         $SOCKETSERVER $DIR/socket ||
5296                 error "$SOCKETSERVER $DIR/socket failed: $?"
5297         $SOCKETCLIENT $DIR/socket ||
5298                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5299         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5300 }
5301 run_test 54a "unix domain socket test =========================="
5302
5303 test_54b() {
5304         f="$DIR/f54b"
5305         mknod $f c 1 3
5306         chmod 0666 $f
5307         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5308 }
5309 run_test 54b "char device works in lustre ======================"
5310
5311 find_loop_dev() {
5312         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5313         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5314         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5315
5316         for i in $(seq 3 7); do
5317                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5318                 LOOPDEV=$LOOPBASE$i
5319                 LOOPNUM=$i
5320                 break
5321         done
5322 }
5323
5324 cleanup_54c() {
5325         local rc=0
5326         loopdev="$DIR/loop54c"
5327
5328         trap 0
5329         $UMOUNT $DIR/$tdir || rc=$?
5330         losetup -d $loopdev || true
5331         losetup -d $LOOPDEV || true
5332         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5333         return $rc
5334 }
5335
5336 test_54c() {
5337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5338
5339         loopdev="$DIR/loop54c"
5340
5341         find_loop_dev
5342         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5343         trap cleanup_54c EXIT
5344         mknod $loopdev b 7 $LOOPNUM
5345         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5346         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5347         losetup $loopdev $DIR/$tfile ||
5348                 error "can't set up $loopdev for $DIR/$tfile"
5349         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5350         test_mkdir $DIR/$tdir
5351         mount -t ext2 $loopdev $DIR/$tdir ||
5352                 error "error mounting $loopdev on $DIR/$tdir"
5353         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5354                 error "dd write"
5355         df $DIR/$tdir
5356         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5357                 error "dd read"
5358         cleanup_54c
5359 }
5360 run_test 54c "block device works in lustre ====================="
5361
5362 test_54d() {
5363         f="$DIR/f54d"
5364         string="aaaaaa"
5365         mknod $f p
5366         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5367 }
5368 run_test 54d "fifo device works in lustre ======================"
5369
5370 test_54e() {
5371         f="$DIR/f54e"
5372         string="aaaaaa"
5373         cp -aL /dev/console $f
5374         echo $string > $f || error "echo $string to $f failed"
5375 }
5376 run_test 54e "console/tty device works in lustre ======================"
5377
5378 test_56a() {
5379         local numfiles=3
5380         local dir=$DIR/$tdir
5381
5382         rm -rf $dir
5383         test_mkdir -p $dir/dir
5384         for i in $(seq $numfiles); do
5385                 touch $dir/file$i
5386                 touch $dir/dir/file$i
5387         done
5388
5389         local numcomp=$($LFS getstripe --component-count $dir)
5390
5391         [[ $numcomp == 0 ]] && numcomp=1
5392
5393         # test lfs getstripe with --recursive
5394         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5395
5396         [[ $filenum -eq $((numfiles * 2)) ]] ||
5397                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5398         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5399         [[ $filenum -eq $numfiles ]] ||
5400                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5401         echo "$LFS getstripe showed obdidx or l_ost_idx"
5402
5403         # test lfs getstripe with file instead of dir
5404         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5405         [[ $filenum -eq 1 ]] ||
5406                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5407         echo "$LFS getstripe file1 passed"
5408
5409         #test lfs getstripe with --verbose
5410         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5411         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5412                 error "$LFS getstripe --verbose $dir: "\
5413                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5414         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5415                 error "$LFS getstripe $dir: showed lmm_magic"
5416
5417         #test lfs getstripe with -v prints lmm_fid
5418         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5419         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5420                 error "$LFS getstripe -v $dir: "\
5421                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5422         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5423                 error "$LFS getstripe $dir: showed lmm_fid by default"
5424         echo "$LFS getstripe --verbose passed"
5425
5426         #check for FID information
5427         local fid1=$($LFS getstripe --fid $dir/file1)
5428         local fid2=$($LFS getstripe --verbose $dir/file1 |
5429                      awk '/lmm_fid: / { print $2; exit; }')
5430         local fid3=$($LFS path2fid $dir/file1)
5431
5432         [ "$fid1" != "$fid2" ] &&
5433                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5434         [ "$fid1" != "$fid3" ] &&
5435                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5436         echo "$LFS getstripe --fid passed"
5437
5438         #test lfs getstripe with --obd
5439         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5440                 error "$LFS getstripe --obd wrong_uuid: should return error"
5441
5442         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5443
5444         local ostidx=1
5445         local obduuid=$(ostuuid_from_index $ostidx)
5446         local found=$($LFS getstripe -r --obd $obduuid $dir |
5447                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5448
5449         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5450         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5451                 ((filenum--))
5452         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5453                 ((filenum--))
5454
5455         [[ $found -eq $filenum ]] ||
5456                 error "$LFS getstripe --obd: found $found expect $filenum"
5457         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5458                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5459                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5460                 error "$LFS getstripe --obd: should not show file on other obd"
5461         echo "$LFS getstripe --obd passed"
5462 }
5463 run_test 56a "check $LFS getstripe"
5464
5465 test_56b() {
5466         local dir=$DIR/$tdir
5467         local numdirs=3
5468
5469         test_mkdir $dir
5470         for i in $(seq $numdirs); do
5471                 test_mkdir $dir/dir$i
5472         done
5473
5474         # test lfs getdirstripe default mode is non-recursion, which is
5475         # different from lfs getstripe
5476         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5477
5478         [[ $dircnt -eq 1 ]] ||
5479                 error "$LFS getdirstripe: found $dircnt, not 1"
5480         dircnt=$($LFS getdirstripe --recursive $dir |
5481                 grep -c lmv_stripe_count)
5482         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5483                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5484 }
5485 run_test 56b "check $LFS getdirstripe"
5486
5487 test_56c() {
5488         remote_ost_nodsh && skip "remote OST with nodsh"
5489
5490         local ost_idx=0
5491         local ost_name=$(ostname_from_index $ost_idx)
5492         local old_status=$(ost_dev_status $ost_idx)
5493
5494         [[ -z "$old_status" ]] ||
5495                 skip_env "OST $ost_name is in $old_status status"
5496
5497         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5498         sleep_maxage
5499
5500         local new_status=$(ost_dev_status $ost_idx)
5501
5502         [[ "$new_status" = "D" ]] ||
5503                 error "OST $ost_name is in status of '$new_status', not 'D'"
5504
5505         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5506         sleep_maxage
5507
5508         new_status=$(ost_dev_status $ost_idx)
5509         [[ -z "$new_status" ]] ||
5510                 error "OST $ost_name is in status of '$new_status', not ''"
5511 }
5512 run_test 56c "check 'lfs df' showing device status"
5513
5514 NUMFILES=3
5515 NUMDIRS=3
5516 setup_56() {
5517         local local_tdir="$1"
5518         local local_numfiles="$2"
5519         local local_numdirs="$3"
5520         local dir_params="$4"
5521         local dir_stripe_params="$5"
5522
5523         if [ ! -d "$local_tdir" ] ; then
5524                 test_mkdir -p $dir_stripe_params $local_tdir
5525                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5526                 for i in $(seq $local_numfiles) ; do
5527                         touch $local_tdir/file$i
5528                 done
5529                 for i in $(seq $local_numdirs) ; do
5530                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5531                         for j in $(seq $local_numfiles) ; do
5532                                 touch $local_tdir/dir$i/file$j
5533                         done
5534                 done
5535         fi
5536 }
5537
5538 setup_56_special() {
5539         local local_tdir=$1
5540         local local_numfiles=$2
5541         local local_numdirs=$3
5542
5543         setup_56 $local_tdir $local_numfiles $local_numdirs
5544
5545         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5546                 for i in $(seq $local_numfiles) ; do
5547                         mknod $local_tdir/loop${i}b b 7 $i
5548                         mknod $local_tdir/null${i}c c 1 3
5549                         ln -s $local_tdir/file1 $local_tdir/link${i}
5550                 done
5551                 for i in $(seq $local_numdirs) ; do
5552                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5553                         mknod $local_tdir/dir$i/null${i}c c 1 3
5554                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5555                 done
5556         fi
5557 }
5558
5559 test_56g() {
5560         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5561         local expected=$(($NUMDIRS + 2))
5562
5563         setup_56 $dir $NUMFILES $NUMDIRS
5564
5565         # test lfs find with -name
5566         for i in $(seq $NUMFILES) ; do
5567                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5568
5569                 [ $nums -eq $expected ] ||
5570                         error "lfs find -name '*$i' $dir wrong: "\
5571                               "found $nums, expected $expected"
5572         done
5573 }
5574 run_test 56g "check lfs find -name"
5575
5576 test_56h() {
5577         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5578         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5579
5580         setup_56 $dir $NUMFILES $NUMDIRS
5581
5582         # test lfs find with ! -name
5583         for i in $(seq $NUMFILES) ; do
5584                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5585
5586                 [ $nums -eq $expected ] ||
5587                         error "lfs find ! -name '*$i' $dir wrong: "\
5588                               "found $nums, expected $expected"
5589         done
5590 }
5591 run_test 56h "check lfs find ! -name"
5592
5593 test_56i() {
5594         local dir=$DIR/$tdir
5595
5596         test_mkdir $dir
5597
5598         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5599         local out=$($cmd)
5600
5601         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5602 }
5603 run_test 56i "check 'lfs find -ost UUID' skips directories"
5604
5605 test_56j() {
5606         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5607
5608         setup_56_special $dir $NUMFILES $NUMDIRS
5609
5610         local expected=$((NUMDIRS + 1))
5611         local cmd="$LFS find -type d $dir"
5612         local nums=$($cmd | wc -l)
5613
5614         [ $nums -eq $expected ] ||
5615                 error "'$cmd' wrong: found $nums, expected $expected"
5616 }
5617 run_test 56j "check lfs find -type d"
5618
5619 test_56k() {
5620         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5621
5622         setup_56_special $dir $NUMFILES $NUMDIRS
5623
5624         local expected=$(((NUMDIRS + 1) * NUMFILES))
5625         local cmd="$LFS find -type f $dir"
5626         local nums=$($cmd | wc -l)
5627
5628         [ $nums -eq $expected ] ||
5629                 error "'$cmd' wrong: found $nums, expected $expected"
5630 }
5631 run_test 56k "check lfs find -type f"
5632
5633 test_56l() {
5634         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5635
5636         setup_56_special $dir $NUMFILES $NUMDIRS
5637
5638         local expected=$((NUMDIRS + NUMFILES))
5639         local cmd="$LFS find -type b $dir"
5640         local nums=$($cmd | wc -l)
5641
5642         [ $nums -eq $expected ] ||
5643                 error "'$cmd' wrong: found $nums, expected $expected"
5644 }
5645 run_test 56l "check lfs find -type b"
5646
5647 test_56m() {
5648         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5649
5650         setup_56_special $dir $NUMFILES $NUMDIRS
5651
5652         local expected=$((NUMDIRS + NUMFILES))
5653         local cmd="$LFS find -type c $dir"
5654         local nums=$($cmd | wc -l)
5655         [ $nums -eq $expected ] ||
5656                 error "'$cmd' wrong: found $nums, expected $expected"
5657 }
5658 run_test 56m "check lfs find -type c"
5659
5660 test_56n() {
5661         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5662         setup_56_special $dir $NUMFILES $NUMDIRS
5663
5664         local expected=$((NUMDIRS + NUMFILES))
5665         local cmd="$LFS find -type l $dir"
5666         local nums=$($cmd | wc -l)
5667
5668         [ $nums -eq $expected ] ||
5669                 error "'$cmd' wrong: found $nums, expected $expected"
5670 }
5671 run_test 56n "check lfs find -type l"
5672
5673 test_56o() {
5674         local dir=$DIR/$tdir
5675
5676         setup_56 $dir $NUMFILES $NUMDIRS
5677         utime $dir/file1 > /dev/null || error "utime (1)"
5678         utime $dir/file2 > /dev/null || error "utime (2)"
5679         utime $dir/dir1 > /dev/null || error "utime (3)"
5680         utime $dir/dir2 > /dev/null || error "utime (4)"
5681         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5682         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5683
5684         local expected=4
5685         local nums=$($LFS find -mtime +0 $dir | wc -l)
5686
5687         [ $nums -eq $expected ] ||
5688                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5689
5690         expected=12
5691         cmd="$LFS find -mtime 0 $dir"
5692         nums=$($cmd | wc -l)
5693         [ $nums -eq $expected ] ||
5694                 error "'$cmd' wrong: found $nums, expected $expected"
5695 }
5696 run_test 56o "check lfs find -mtime for old files"
5697
5698 test_56ob() {
5699         local dir=$DIR/$tdir
5700         local expected=1
5701         local count=0
5702
5703         # just to make sure there is something that won't be found
5704         test_mkdir $dir
5705         touch $dir/$tfile.now
5706
5707         for age in year week day hour min; do
5708                 count=$((count + 1))
5709
5710                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5711                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5712                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5713
5714                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5715                 local nums=$($cmd | wc -l)
5716                 [ $nums -eq $expected ] ||
5717                         error "'$cmd' wrong: found $nums, expected $expected"
5718
5719                 cmd="$LFS find $dir -atime $count${age:0:1}"
5720                 nums=$($cmd | wc -l)
5721                 [ $nums -eq $expected ] ||
5722                         error "'$cmd' wrong: found $nums, expected $expected"
5723         done
5724
5725         sleep 2
5726         cmd="$LFS find $dir -ctime +1s -type f"
5727         nums=$($cmd | wc -l)
5728         (( $nums == $count * 2 + 1)) ||
5729                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5730 }
5731 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5732
5733 test_56p() {
5734         [ $RUNAS_ID -eq $UID ] &&
5735                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5736
5737         local dir=$DIR/$tdir
5738
5739         setup_56 $dir $NUMFILES $NUMDIRS
5740         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5741
5742         local expected=$NUMFILES
5743         local cmd="$LFS find -uid $RUNAS_ID $dir"
5744         local nums=$($cmd | wc -l)
5745
5746         [ $nums -eq $expected ] ||
5747                 error "'$cmd' wrong: found $nums, expected $expected"
5748
5749         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5750         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5751         nums=$($cmd | wc -l)
5752         [ $nums -eq $expected ] ||
5753                 error "'$cmd' wrong: found $nums, expected $expected"
5754 }
5755 run_test 56p "check lfs find -uid and ! -uid"
5756
5757 test_56q() {
5758         [ $RUNAS_ID -eq $UID ] &&
5759                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5760
5761         local dir=$DIR/$tdir
5762
5763         setup_56 $dir $NUMFILES $NUMDIRS
5764         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5765
5766         local expected=$NUMFILES
5767         local cmd="$LFS find -gid $RUNAS_GID $dir"
5768         local nums=$($cmd | wc -l)
5769
5770         [ $nums -eq $expected ] ||
5771                 error "'$cmd' wrong: found $nums, expected $expected"
5772
5773         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5774         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5775         nums=$($cmd | wc -l)
5776         [ $nums -eq $expected ] ||
5777                 error "'$cmd' wrong: found $nums, expected $expected"
5778 }
5779 run_test 56q "check lfs find -gid and ! -gid"
5780
5781 test_56r() {
5782         local dir=$DIR/$tdir
5783
5784         setup_56 $dir $NUMFILES $NUMDIRS
5785
5786         local expected=12
5787         local cmd="$LFS find -size 0 -type f -lazy $dir"
5788         local nums=$($cmd | wc -l)
5789
5790         [ $nums -eq $expected ] ||
5791                 error "'$cmd' wrong: found $nums, expected $expected"
5792         cmd="$LFS find -size 0 -type f $dir"
5793         nums=$($cmd | wc -l)
5794         [ $nums -eq $expected ] ||
5795                 error "'$cmd' wrong: found $nums, expected $expected"
5796
5797         expected=0
5798         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5799         nums=$($cmd | wc -l)
5800         [ $nums -eq $expected ] ||
5801                 error "'$cmd' wrong: found $nums, expected $expected"
5802         cmd="$LFS find ! -size 0 -type f $dir"
5803         nums=$($cmd | wc -l)
5804         [ $nums -eq $expected ] ||
5805                 error "'$cmd' wrong: found $nums, expected $expected"
5806
5807         echo "test" > $dir/$tfile
5808         echo "test2" > $dir/$tfile.2 && sync
5809         expected=1
5810         cmd="$LFS find -size 5 -type f -lazy $dir"
5811         nums=$($cmd | wc -l)
5812         [ $nums -eq $expected ] ||
5813                 error "'$cmd' wrong: found $nums, expected $expected"
5814         cmd="$LFS find -size 5 -type f $dir"
5815         nums=$($cmd | wc -l)
5816         [ $nums -eq $expected ] ||
5817                 error "'$cmd' wrong: found $nums, expected $expected"
5818
5819         expected=1
5820         cmd="$LFS find -size +5 -type f -lazy $dir"
5821         nums=$($cmd | wc -l)
5822         [ $nums -eq $expected ] ||
5823                 error "'$cmd' wrong: found $nums, expected $expected"
5824         cmd="$LFS find -size +5 -type f $dir"
5825         nums=$($cmd | wc -l)
5826         [ $nums -eq $expected ] ||
5827                 error "'$cmd' wrong: found $nums, expected $expected"
5828
5829         expected=2
5830         cmd="$LFS find -size +0 -type f -lazy $dir"
5831         nums=$($cmd | wc -l)
5832         [ $nums -eq $expected ] ||
5833                 error "'$cmd' wrong: found $nums, expected $expected"
5834         cmd="$LFS find -size +0 -type f $dir"
5835         nums=$($cmd | wc -l)
5836         [ $nums -eq $expected ] ||
5837                 error "'$cmd' wrong: found $nums, expected $expected"
5838
5839         expected=2
5840         cmd="$LFS find ! -size -5 -type f -lazy $dir"
5841         nums=$($cmd | wc -l)
5842         [ $nums -eq $expected ] ||
5843                 error "'$cmd' wrong: found $nums, expected $expected"
5844         cmd="$LFS find ! -size -5 -type f $dir"
5845         nums=$($cmd | wc -l)
5846         [ $nums -eq $expected ] ||
5847                 error "'$cmd' wrong: found $nums, expected $expected"
5848
5849         expected=12
5850         cmd="$LFS find -size -5 -type f -lazy $dir"
5851         nums=$($cmd | wc -l)
5852         [ $nums -eq $expected ] ||
5853                 error "'$cmd' wrong: found $nums, expected $expected"
5854         cmd="$LFS find -size -5 -type f $dir"
5855         nums=$($cmd | wc -l)
5856         [ $nums -eq $expected ] ||
5857                 error "'$cmd' wrong: found $nums, expected $expected"
5858 }
5859 run_test 56r "check lfs find -size works"
5860
5861 test_56ra() {
5862         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
5863                 skip "MDS < 2.12.58 doesn't return LSOM data"
5864         local dir=$DIR/$tdir
5865
5866         [[ $OSC == "mdc" ]] && skip "DoM files" && return
5867
5868         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5869
5870         cancel_lru_locks $OSC
5871
5872         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5873         local expected=12
5874         local cmd="$LFS find -size 0 -type f -lazy $dir"
5875         local nums=$($cmd | wc -l)
5876
5877         [ $nums -eq $expected ] ||
5878                 error "'$cmd' wrong: found $nums, expected $expected"
5879
5880         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5881         [ $rpcs_before -eq $rpcs_after ] ||
5882                 error "'$cmd' should not send glimpse RPCs to OST"
5883         cmd="$LFS find -size 0 -type f $dir"
5884         nums=$($cmd | wc -l)
5885         [ $nums -eq $expected ] ||
5886                 error "'$cmd' wrong: found $nums, expected $expected"
5887         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5888         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5889         $LCTL get_param osc.*.stats
5890         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
5891                 error "'$cmd' should send 12 glimpse RPCs to OST"
5892
5893         cancel_lru_locks $OSC
5894         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5895         expected=0
5896         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5897         nums=$($cmd | wc -l)
5898         [ $nums -eq $expected ] ||
5899                 error "'$cmd' wrong: found $nums, expected $expected"
5900         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5901         $LCTL get_param mdc.*.stats
5902         [ $rpcs_before -eq $rpcs_after ] ||
5903                 error "'$cmd' should not send glimpse RPCs to OST"
5904         cmd="$LFS find ! -size 0 -type f $dir"
5905         nums=$($cmd | wc -l)
5906         [ $nums -eq $expected ] ||
5907                 error "'$cmd' wrong: found $nums, expected $expected"
5908         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5909         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5910         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
5911                 error "'$cmd' should send 12 glimpse RPCs to OST"
5912
5913         echo "test" > $dir/$tfile
5914         echo "test2" > $dir/$tfile.2 && sync
5915         cancel_lru_locks $OSC
5916         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5917         expected=1
5918         cmd="$LFS find -size 5 -type f -lazy $dir"
5919         nums=$($cmd | wc -l)
5920         [ $nums -eq $expected ] ||
5921                 error "'$cmd' wrong: found $nums, expected $expected"
5922         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5923         [ $rpcs_before -eq $rpcs_after ] ||
5924                 error "'$cmd' should not send glimpse RPCs to OST"
5925         cmd="$LFS find -size 5 -type f $dir"
5926         nums=$($cmd | wc -l)
5927         [ $nums -eq $expected ] ||
5928                 error "'$cmd' wrong: found $nums, expected $expected"
5929         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5930         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5931         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5932                 error "'$cmd' should send 14 glimpse RPCs to OST"
5933
5934         cancel_lru_locks $OSC
5935         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5936         expected=1
5937         cmd="$LFS find -size +5 -type f -lazy $dir"
5938         nums=$($cmd | wc -l)
5939         [ $nums -eq $expected ] ||
5940                 error "'$cmd' wrong: found $nums, expected $expected"
5941         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5942         [ $rpcs_before -eq $rpcs_after ] ||
5943                 error "'$cmd' should not send glimpse RPCs to OST"
5944         cmd="$LFS find -size +5 -type f $dir"
5945         nums=$($cmd | wc -l)
5946         [ $nums -eq $expected ] ||
5947                 error "'$cmd' wrong: found $nums, expected $expected"
5948         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5949         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5950         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5951                 error "'$cmd' should send 14 glimpse RPCs to OST"
5952
5953         cancel_lru_locks $OSC
5954         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5955         expected=2
5956         cmd="$LFS find -size +0 -type f -lazy $dir"
5957         nums=$($cmd | wc -l)
5958         [ $nums -eq $expected ] ||
5959                 error "'$cmd' wrong: found $nums, expected $expected"
5960         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5961         [ $rpcs_before -eq $rpcs_after ] ||
5962                 error "'$cmd' should not send glimpse RPCs to OST"
5963         cmd="$LFS find -size +0 -type f $dir"
5964         nums=$($cmd | wc -l)
5965         [ $nums -eq $expected ] ||
5966                 error "'$cmd' wrong: found $nums, expected $expected"
5967         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5968         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5969         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5970                 error "'$cmd' should send 14 glimpse RPCs to OST"
5971
5972         cancel_lru_locks $OSC
5973         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5974         expected=2
5975         cmd="$LFS find ! -size -5 -type f -lazy $dir"
5976         nums=$($cmd | wc -l)
5977         [ $nums -eq $expected ] ||
5978                 error "'$cmd' wrong: found $nums, expected $expected"
5979         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5980         [ $rpcs_before -eq $rpcs_after ] ||
5981                 error "'$cmd' should not send glimpse RPCs to OST"
5982         cmd="$LFS find ! -size -5 -type f $dir"
5983         nums=$($cmd | wc -l)
5984         [ $nums -eq $expected ] ||
5985                 error "'$cmd' wrong: found $nums, expected $expected"
5986         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5987         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5988         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5989                 error "'$cmd' should send 14 glimpse RPCs to OST"
5990
5991         cancel_lru_locks $OSC
5992         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5993         expected=12
5994         cmd="$LFS find -size -5 -type f -lazy $dir"
5995         nums=$($cmd | wc -l)
5996         [ $nums -eq $expected ] ||
5997                 error "'$cmd' wrong: found $nums, expected $expected"
5998         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5999         [ $rpcs_before -eq $rpcs_after ] ||
6000                 error "'$cmd' should not send glimpse RPCs to OST"
6001         cmd="$LFS find -size -5 -type f $dir"
6002         nums=$($cmd | wc -l)
6003         [ $nums -eq $expected ] ||
6004                 error "'$cmd' wrong: found $nums, expected $expected"
6005         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6006         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6007         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6008                 error "'$cmd' should send 14 glimpse RPCs to OST"
6009 }
6010 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6011
6012 test_56s() { # LU-611 #LU-9369
6013         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6014
6015         local dir=$DIR/$tdir
6016         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6017
6018         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6019         for i in $(seq $NUMDIRS); do
6020                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6021         done
6022
6023         local expected=$NUMDIRS
6024         local cmd="$LFS find -c $OSTCOUNT $dir"
6025         local nums=$($cmd | wc -l)
6026
6027         [ $nums -eq $expected ] || {
6028                 $LFS getstripe -R $dir
6029                 error "'$cmd' wrong: found $nums, expected $expected"
6030         }
6031
6032         expected=$((NUMDIRS + onestripe))
6033         cmd="$LFS find -stripe-count +0 -type f $dir"
6034         nums=$($cmd | wc -l)
6035         [ $nums -eq $expected ] || {
6036                 $LFS getstripe -R $dir
6037                 error "'$cmd' wrong: found $nums, expected $expected"
6038         }
6039
6040         expected=$onestripe
6041         cmd="$LFS find -stripe-count 1 -type f $dir"
6042         nums=$($cmd | wc -l)
6043         [ $nums -eq $expected ] || {
6044                 $LFS getstripe -R $dir
6045                 error "'$cmd' wrong: found $nums, expected $expected"
6046         }
6047
6048         cmd="$LFS find -stripe-count -2 -type f $dir"
6049         nums=$($cmd | wc -l)
6050         [ $nums -eq $expected ] || {
6051                 $LFS getstripe -R $dir
6052                 error "'$cmd' wrong: found $nums, expected $expected"
6053         }
6054
6055         expected=0
6056         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6057         nums=$($cmd | wc -l)
6058         [ $nums -eq $expected ] || {
6059                 $LFS getstripe -R $dir
6060                 error "'$cmd' wrong: found $nums, expected $expected"
6061         }
6062 }
6063 run_test 56s "check lfs find -stripe-count works"
6064
6065 test_56t() { # LU-611 #LU-9369
6066         local dir=$DIR/$tdir
6067
6068         setup_56 $dir 0 $NUMDIRS
6069         for i in $(seq $NUMDIRS); do
6070                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6071         done
6072
6073         local expected=$NUMDIRS
6074         local cmd="$LFS find -S 8M $dir"
6075         local nums=$($cmd | wc -l)
6076
6077         [ $nums -eq $expected ] || {
6078                 $LFS getstripe -R $dir
6079                 error "'$cmd' wrong: found $nums, expected $expected"
6080         }
6081         rm -rf $dir
6082
6083         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6084
6085         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6086
6087         expected=$(((NUMDIRS + 1) * NUMFILES))
6088         cmd="$LFS find -stripe-size 512k -type f $dir"
6089         nums=$($cmd | wc -l)
6090         [ $nums -eq $expected ] ||
6091                 error "'$cmd' wrong: found $nums, expected $expected"
6092
6093         cmd="$LFS find -stripe-size +320k -type f $dir"
6094         nums=$($cmd | wc -l)
6095         [ $nums -eq $expected ] ||
6096                 error "'$cmd' wrong: found $nums, expected $expected"
6097
6098         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6099         cmd="$LFS find -stripe-size +200k -type f $dir"
6100         nums=$($cmd | wc -l)
6101         [ $nums -eq $expected ] ||
6102                 error "'$cmd' wrong: found $nums, expected $expected"
6103
6104         cmd="$LFS find -stripe-size -640k -type f $dir"
6105         nums=$($cmd | wc -l)
6106         [ $nums -eq $expected ] ||
6107                 error "'$cmd' wrong: found $nums, expected $expected"
6108
6109         expected=4
6110         cmd="$LFS find -stripe-size 256k -type f $dir"
6111         nums=$($cmd | wc -l)
6112         [ $nums -eq $expected ] ||
6113                 error "'$cmd' wrong: found $nums, expected $expected"
6114
6115         cmd="$LFS find -stripe-size -320k -type f $dir"
6116         nums=$($cmd | wc -l)
6117         [ $nums -eq $expected ] ||
6118                 error "'$cmd' wrong: found $nums, expected $expected"
6119
6120         expected=0
6121         cmd="$LFS find -stripe-size 1024k -type f $dir"
6122         nums=$($cmd | wc -l)
6123         [ $nums -eq $expected ] ||
6124                 error "'$cmd' wrong: found $nums, expected $expected"
6125 }
6126 run_test 56t "check lfs find -stripe-size works"
6127
6128 test_56u() { # LU-611
6129         local dir=$DIR/$tdir
6130
6131         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6132
6133         if [[ $OSTCOUNT -gt 1 ]]; then
6134                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6135                 onestripe=4
6136         else
6137                 onestripe=0
6138         fi
6139
6140         local expected=$(((NUMDIRS + 1) * NUMFILES))
6141         local cmd="$LFS find -stripe-index 0 -type f $dir"
6142         local nums=$($cmd | wc -l)
6143
6144         [ $nums -eq $expected ] ||
6145                 error "'$cmd' wrong: found $nums, expected $expected"
6146
6147         expected=$onestripe
6148         cmd="$LFS find -stripe-index 1 -type f $dir"
6149         nums=$($cmd | wc -l)
6150         [ $nums -eq $expected ] ||
6151                 error "'$cmd' wrong: found $nums, expected $expected"
6152
6153         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6154         nums=$($cmd | wc -l)
6155         [ $nums -eq $expected ] ||
6156                 error "'$cmd' wrong: found $nums, expected $expected"
6157
6158         expected=0
6159         # This should produce an error and not return any files
6160         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6161         nums=$($cmd 2>/dev/null | wc -l)
6162         [ $nums -eq $expected ] ||
6163                 error "'$cmd' wrong: found $nums, expected $expected"
6164
6165         if [[ $OSTCOUNT -gt 1 ]]; then
6166                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6167                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6168                 nums=$($cmd | wc -l)
6169                 [ $nums -eq $expected ] ||
6170                         error "'$cmd' wrong: found $nums, expected $expected"
6171         fi
6172 }
6173 run_test 56u "check lfs find -stripe-index works"
6174
6175 test_56v() {
6176         local mdt_idx=0
6177         local dir=$DIR/$tdir
6178
6179         setup_56 $dir $NUMFILES $NUMDIRS
6180
6181         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6182         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6183
6184         for file in $($LFS find -m $UUID $dir); do
6185                 file_midx=$($LFS getstripe -m $file)
6186                 [ $file_midx -eq $mdt_idx ] ||
6187                         error "lfs find -m $UUID != getstripe -m $file_midx"
6188         done
6189 }
6190 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6191
6192 test_56w() {
6193         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6195
6196         local dir=$DIR/$tdir
6197
6198         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6199
6200         local stripe_size=$($LFS getstripe -S -d $dir) ||
6201                 error "$LFS getstripe -S -d $dir failed"
6202         stripe_size=${stripe_size%% *}
6203
6204         local file_size=$((stripe_size * OSTCOUNT))
6205         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6206         local required_space=$((file_num * file_size))
6207         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6208                            head -n1)
6209         [[ $free_space -le $((required_space / 1024)) ]] &&
6210                 skip_env "need $required_space, have $free_space kbytes"
6211
6212         local dd_bs=65536
6213         local dd_count=$((file_size / dd_bs))
6214
6215         # write data into the files
6216         local i
6217         local j
6218         local file
6219
6220         for i in $(seq $NUMFILES); do
6221                 file=$dir/file$i
6222                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6223                         error "write data into $file failed"
6224         done
6225         for i in $(seq $NUMDIRS); do
6226                 for j in $(seq $NUMFILES); do
6227                         file=$dir/dir$i/file$j
6228                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6229                                 error "write data into $file failed"
6230                 done
6231         done
6232
6233         # $LFS_MIGRATE will fail if hard link migration is unsupported
6234         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6235                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6236                         error "creating links to $dir/dir1/file1 failed"
6237         fi
6238
6239         local expected=-1
6240
6241         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6242
6243         # lfs_migrate file
6244         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6245
6246         echo "$cmd"
6247         eval $cmd || error "$cmd failed"
6248
6249         check_stripe_count $dir/file1 $expected
6250
6251         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6252         then
6253                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6254                 # OST 1 if it is on OST 0. This file is small enough to
6255                 # be on only one stripe.
6256                 file=$dir/migr_1_ost
6257                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6258                         error "write data into $file failed"
6259                 local obdidx=$($LFS getstripe -i $file)
6260                 local oldmd5=$(md5sum $file)
6261                 local newobdidx=0
6262
6263                 [[ $obdidx -eq 0 ]] && newobdidx=1
6264                 cmd="$LFS migrate -i $newobdidx $file"
6265                 echo $cmd
6266                 eval $cmd || error "$cmd failed"
6267
6268                 local realobdix=$($LFS getstripe -i $file)
6269                 local newmd5=$(md5sum $file)
6270
6271                 [[ $newobdidx -ne $realobdix ]] &&
6272                         error "new OST is different (was=$obdidx, "\
6273                               "wanted=$newobdidx, got=$realobdix)"
6274                 [[ "$oldmd5" != "$newmd5" ]] &&
6275                         error "md5sum differ: $oldmd5, $newmd5"
6276         fi
6277
6278         # lfs_migrate dir
6279         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6280         echo "$cmd"
6281         eval $cmd || error "$cmd failed"
6282
6283         for j in $(seq $NUMFILES); do
6284                 check_stripe_count $dir/dir1/file$j $expected
6285         done
6286
6287         # lfs_migrate works with lfs find
6288         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6289              $LFS_MIGRATE -y -c $expected"
6290         echo "$cmd"
6291         eval $cmd || error "$cmd failed"
6292
6293         for i in $(seq 2 $NUMFILES); do
6294                 check_stripe_count $dir/file$i $expected
6295         done
6296         for i in $(seq 2 $NUMDIRS); do
6297                 for j in $(seq $NUMFILES); do
6298                 check_stripe_count $dir/dir$i/file$j $expected
6299                 done
6300         done
6301 }
6302 run_test 56w "check lfs_migrate -c stripe_count works"
6303
6304 test_56wb() {
6305         local file1=$DIR/$tdir/file1
6306         local create_pool=false
6307         local initial_pool=$($LFS getstripe -p $DIR)
6308         local pool_list=()
6309         local pool=""
6310
6311         echo -n "Creating test dir..."
6312         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6313         echo "done."
6314
6315         echo -n "Creating test file..."
6316         touch $file1 || error "cannot create file"
6317         echo "done."
6318
6319         echo -n "Detecting existing pools..."
6320         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6321
6322         if [ ${#pool_list[@]} -gt 0 ]; then
6323                 echo "${pool_list[@]}"
6324                 for thispool in "${pool_list[@]}"; do
6325                         if [[ -z "$initial_pool" ||
6326                               "$initial_pool" != "$thispool" ]]; then
6327                                 pool="$thispool"
6328                                 echo "Using existing pool '$pool'"
6329                                 break
6330                         fi
6331                 done
6332         else
6333                 echo "none detected."
6334         fi
6335         if [ -z "$pool" ]; then
6336                 pool=${POOL:-testpool}
6337                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6338                 echo -n "Creating pool '$pool'..."
6339                 create_pool=true
6340                 pool_add $pool &> /dev/null ||
6341                         error "pool_add failed"
6342                 echo "done."
6343
6344                 echo -n "Adding target to pool..."
6345                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6346                         error "pool_add_targets failed"
6347                 echo "done."
6348         fi
6349
6350         echo -n "Setting pool using -p option..."
6351         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6352                 error "migrate failed rc = $?"
6353         echo "done."
6354
6355         echo -n "Verifying test file is in pool after migrating..."
6356         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6357                 error "file was not migrated to pool $pool"
6358         echo "done."
6359
6360         echo -n "Removing test file from pool '$pool'..."
6361         $LFS migrate $file1 &> /dev/null ||
6362                 error "cannot remove from pool"
6363         [ "$($LFS getstripe -p $file1)" ] &&
6364                 error "pool still set"
6365         echo "done."
6366
6367         echo -n "Setting pool using --pool option..."
6368         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6369                 error "migrate failed rc = $?"
6370         echo "done."
6371
6372         # Clean up
6373         rm -f $file1
6374         if $create_pool; then
6375                 destroy_test_pools 2> /dev/null ||
6376                         error "destroy test pools failed"
6377         fi
6378 }
6379 run_test 56wb "check lfs_migrate pool support"
6380
6381 test_56wc() {
6382         local file1="$DIR/$tdir/file1"
6383
6384         echo -n "Creating test dir..."
6385         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6386         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6387         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6388                 error "cannot set stripe"
6389         echo "done"
6390
6391         echo -n "Setting initial stripe for test file..."
6392         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6393                 error "cannot set stripe"
6394         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6395                 error "stripe size not set"
6396         echo "done."
6397
6398         # File currently set to -S 512K -c 1
6399
6400         # Ensure -c and -S options are rejected when -R is set
6401         echo -n "Verifying incompatible options are detected..."
6402         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6403                 error "incompatible -c and -R options not detected"
6404         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6405                 error "incompatible -S and -R options not detected"
6406         echo "done."
6407
6408         # Ensure unrecognized options are passed through to 'lfs migrate'
6409         echo -n "Verifying -S option is passed through to lfs migrate..."
6410         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6411                 error "migration failed"
6412         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6413                 error "file was not restriped"
6414         echo "done."
6415
6416         # File currently set to -S 1M -c 1
6417
6418         # Ensure long options are supported
6419         echo -n "Verifying long options supported..."
6420         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6421                 error "long option without argument not supported"
6422         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6423                 error "long option with argument not supported"
6424         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6425                 error "file not restriped with --stripe-size option"
6426         echo "done."
6427
6428         # File currently set to -S 512K -c 1
6429
6430         if [ "$OSTCOUNT" -gt 1 ]; then
6431                 echo -n "Verifying explicit stripe count can be set..."
6432                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6433                         error "migrate failed"
6434                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6435                         error "file not restriped to explicit count"
6436                 echo "done."
6437         fi
6438
6439         # File currently set to -S 512K -c 1 or -S 512K -c 2
6440
6441         # Ensure parent striping is used if -R is set, and no stripe
6442         # count or size is specified
6443         echo -n "Setting stripe for parent directory..."
6444         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6445                 error "cannot set stripe"
6446         echo "done."
6447
6448         echo -n "Verifying restripe option uses parent stripe settings..."
6449         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6450                 error "migrate failed"
6451         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6452                 error "file not restriped to parent settings"
6453         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6454                 error "file not restriped to parent settings"
6455         echo "done."
6456
6457         # File currently set to -S 1M -c 1
6458
6459         # Ensure striping is preserved if -R is not set, and no stripe
6460         # count or size is specified
6461         echo -n "Verifying striping size preserved when not specified..."
6462         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6463         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6464                 error "cannot set stripe on parent directory"
6465         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6466                 error "migrate failed"
6467         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6468                 error "file was restriped"
6469         echo "done."
6470
6471         # Ensure file name properly detected when final option has no argument
6472         echo -n "Verifying file name properly detected..."
6473         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6474                 error "file name interpreted as option argument"
6475         echo "done."
6476
6477         # Clean up
6478         rm -f "$file1"
6479 }
6480 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6481
6482 test_56wd() {
6483         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6484
6485         local file1=$DIR/$tdir/file1
6486
6487         echo -n "Creating test dir..."
6488         test_mkdir $DIR/$tdir || error "cannot create dir"
6489         echo "done."
6490
6491         echo -n "Creating test file..."
6492         touch $file1
6493         echo "done."
6494
6495         # Ensure 'lfs migrate' will fail by using a non-existent option,
6496         # and make sure rsync is not called to recover
6497         echo -n "Make sure --no-rsync option works..."
6498         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6499                 grep -q 'refusing to fall back to rsync' ||
6500                 error "rsync was called with --no-rsync set"
6501         echo "done."
6502
6503         # Ensure rsync is called without trying 'lfs migrate' first
6504         echo -n "Make sure --rsync option works..."
6505         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6506                 grep -q 'falling back to rsync' &&
6507                 error "lfs migrate was called with --rsync set"
6508         echo "done."
6509
6510         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6511         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6512                 grep -q 'at the same time' ||
6513                 error "--rsync and --no-rsync accepted concurrently"
6514         echo "done."
6515
6516         # Clean up
6517         rm -f $file1
6518 }
6519 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6520
6521 test_56x() {
6522         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6523         check_swap_layouts_support
6524
6525         local dir=$DIR/$tdir
6526         local ref1=/etc/passwd
6527         local file1=$dir/file1
6528
6529         test_mkdir $dir || error "creating dir $dir"
6530         $LFS setstripe -c 2 $file1
6531         cp $ref1 $file1
6532         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6533         stripe=$($LFS getstripe -c $file1)
6534         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6535         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6536
6537         # clean up
6538         rm -f $file1
6539 }
6540 run_test 56x "lfs migration support"
6541
6542 test_56xa() {
6543         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6544         check_swap_layouts_support
6545
6546         local dir=$DIR/$tdir/$testnum
6547
6548         test_mkdir -p $dir
6549
6550         local ref1=/etc/passwd
6551         local file1=$dir/file1
6552
6553         $LFS setstripe -c 2 $file1
6554         cp $ref1 $file1
6555         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6556
6557         local stripe=$($LFS getstripe -c $file1)
6558
6559         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6560         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6561
6562         # clean up
6563         rm -f $file1
6564 }
6565 run_test 56xa "lfs migration --block support"
6566
6567 check_migrate_links() {
6568         local dir="$1"
6569         local file1="$dir/file1"
6570         local begin="$2"
6571         local count="$3"
6572         local runas="$4"
6573         local total_count=$(($begin + $count - 1))
6574         local symlink_count=10
6575         local uniq_count=10
6576
6577         if [ ! -f "$file1" ]; then
6578                 echo -n "creating initial file..."
6579                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6580                         error "cannot setstripe initial file"
6581                 echo "done"
6582
6583                 echo -n "creating symlinks..."
6584                 for s in $(seq 1 $symlink_count); do
6585                         ln -s "$file1" "$dir/slink$s" ||
6586                                 error "cannot create symlinks"
6587                 done
6588                 echo "done"
6589
6590                 echo -n "creating nonlinked files..."
6591                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6592                         error "cannot create nonlinked files"
6593                 echo "done"
6594         fi
6595
6596         # create hard links
6597         if [ ! -f "$dir/file$total_count" ]; then
6598                 echo -n "creating hard links $begin:$total_count..."
6599                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6600                         /dev/null || error "cannot create hard links"
6601                 echo "done"
6602         fi
6603
6604         echo -n "checking number of hard links listed in xattrs..."
6605         local fid=$($LFS getstripe -F "$file1")
6606         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6607
6608         echo "${#paths[*]}"
6609         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6610                         skip "hard link list has unexpected size, skipping test"
6611         fi
6612         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6613                         error "link names should exceed xattrs size"
6614         fi
6615
6616         echo -n "migrating files..."
6617         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6618         local rc=$?
6619         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6620         echo "done"
6621
6622         # make sure all links have been properly migrated
6623         echo -n "verifying files..."
6624         fid=$($LFS getstripe -F "$file1") ||
6625                 error "cannot get fid for file $file1"
6626         for i in $(seq 2 $total_count); do
6627                 local fid2=$($LFS getstripe -F $dir/file$i)
6628
6629                 [ "$fid2" == "$fid" ] ||
6630                         error "migrated hard link has mismatched FID"
6631         done
6632
6633         # make sure hard links were properly detected, and migration was
6634         # performed only once for the entire link set; nonlinked files should
6635         # also be migrated
6636         local actual=$(grep -c 'done' <<< "$migrate_out")
6637         local expected=$(($uniq_count + 1))
6638
6639         [ "$actual" -eq  "$expected" ] ||
6640                 error "hard links individually migrated ($actual != $expected)"
6641
6642         # make sure the correct number of hard links are present
6643         local hardlinks=$(stat -c '%h' "$file1")
6644
6645         [ $hardlinks -eq $total_count ] ||
6646                 error "num hard links $hardlinks != $total_count"
6647         echo "done"
6648
6649         return 0
6650 }
6651
6652 test_56xb() {
6653         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6654                 skip "Need MDS version at least 2.10.55"
6655
6656         local dir="$DIR/$tdir"
6657
6658         test_mkdir "$dir" || error "cannot create dir $dir"
6659
6660         echo "testing lfs migrate mode when all links fit within xattrs"
6661         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6662
6663         echo "testing rsync mode when all links fit within xattrs"
6664         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6665
6666         echo "testing lfs migrate mode when all links do not fit within xattrs"
6667         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6668
6669         echo "testing rsync mode when all links do not fit within xattrs"
6670         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6671
6672         chown -R $RUNAS_ID $dir
6673         echo "testing non-root lfs migrate mode when not all links are in xattr"
6674         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
6675
6676         # clean up
6677         rm -rf $dir
6678 }
6679 run_test 56xb "lfs migration hard link support"
6680
6681 test_56xc() {
6682         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6683
6684         local dir="$DIR/$tdir"
6685
6686         test_mkdir "$dir" || error "cannot create dir $dir"
6687
6688         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6689         echo -n "Setting initial stripe for 20MB test file..."
6690         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6691                 error "cannot setstripe 20MB file"
6692         echo "done"
6693         echo -n "Sizing 20MB test file..."
6694         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6695         echo "done"
6696         echo -n "Verifying small file autostripe count is 1..."
6697         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6698                 error "cannot migrate 20MB file"
6699         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6700                 error "cannot get stripe for $dir/20mb"
6701         [ $stripe_count -eq 1 ] ||
6702                 error "unexpected stripe count $stripe_count for 20MB file"
6703         rm -f "$dir/20mb"
6704         echo "done"
6705
6706         # Test 2: File is small enough to fit within the available space on
6707         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6708         # have at least an additional 1KB for each desired stripe for test 3
6709         echo -n "Setting stripe for 1GB test file..."
6710         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
6711         echo "done"
6712         echo -n "Sizing 1GB test file..."
6713         # File size is 1GB + 3KB
6714         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
6715         echo "done"
6716
6717         # need at least 512MB per OST for 1GB file to fit in 2 stripes
6718         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
6719         if (( avail > 524288 * OSTCOUNT )); then
6720                 echo -n "Migrating 1GB file..."
6721                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
6722                         error "cannot migrate 1GB file"
6723                 echo "done"
6724                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
6725                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6726                         error "cannot getstripe for 1GB file"
6727                 [ $stripe_count -eq 2 ] ||
6728                         error "unexpected stripe count $stripe_count != 2"
6729                 echo "done"
6730         fi
6731
6732         # Test 3: File is too large to fit within the available space on
6733         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6734         if [ $OSTCOUNT -ge 3 ]; then
6735                 # The required available space is calculated as
6736                 # file size (1GB + 3KB) / OST count (3).
6737                 local kb_per_ost=349526
6738
6739                 echo -n "Migrating 1GB file with limit..."
6740                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
6741                         error "cannot migrate 1GB file with limit"
6742                 echo "done"
6743
6744                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6745                 echo -n "Verifying 1GB autostripe count with limited space..."
6746                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
6747                         error "unexpected stripe count $stripe_count (min 3)"
6748                 echo "done"
6749         fi
6750
6751         # clean up
6752         rm -rf $dir
6753 }
6754 run_test 56xc "lfs migration autostripe"
6755
6756 test_56y() {
6757         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6758                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6759
6760         local res=""
6761         local dir=$DIR/$tdir
6762         local f1=$dir/file1
6763         local f2=$dir/file2
6764
6765         test_mkdir -p $dir || error "creating dir $dir"
6766         touch $f1 || error "creating std file $f1"
6767         $MULTIOP $f2 H2c || error "creating released file $f2"
6768
6769         # a directory can be raid0, so ask only for files
6770         res=$($LFS find $dir -L raid0 -type f | wc -l)
6771         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6772
6773         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6774         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6775
6776         # only files can be released, so no need to force file search
6777         res=$($LFS find $dir -L released)
6778         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6779
6780         res=$($LFS find $dir -type f \! -L released)
6781         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6782 }
6783 run_test 56y "lfs find -L raid0|released"
6784
6785 test_56z() { # LU-4824
6786         # This checks to make sure 'lfs find' continues after errors
6787         # There are two classes of errors that should be caught:
6788         # - If multiple paths are provided, all should be searched even if one
6789         #   errors out
6790         # - If errors are encountered during the search, it should not terminate
6791         #   early
6792         local dir=$DIR/$tdir
6793         local i
6794
6795         test_mkdir $dir
6796         for i in d{0..9}; do
6797                 test_mkdir $dir/$i
6798                 touch $dir/$i/$tfile
6799         done
6800         $LFS find $DIR/non_existent_dir $dir &&
6801                 error "$LFS find did not return an error"
6802         # Make a directory unsearchable. This should NOT be the last entry in
6803         # directory order.  Arbitrarily pick the 6th entry
6804         chmod 700 $($LFS find $dir -type d | sed '6!d')
6805
6806         $RUNAS $LFS find $DIR/non_existent $dir
6807         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6808
6809         # The user should be able to see 10 directories and 9 files
6810         (( count == 19 )) ||
6811                 error "$LFS find found $count != 19 entries after error"
6812 }
6813 run_test 56z "lfs find should continue after an error"
6814
6815 test_56aa() { # LU-5937
6816         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6817
6818         local dir=$DIR/$tdir
6819
6820         mkdir $dir
6821         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6822
6823         createmany -o $dir/striped_dir/${tfile}- 1024
6824         local dirs=$($LFS find --size +8k $dir/)
6825
6826         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6827 }
6828 run_test 56aa "lfs find --size under striped dir"
6829
6830 test_56ab() { # LU-10705
6831         test_mkdir $DIR/$tdir
6832         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6833         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6834         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6835         # Flush writes to ensure valid blocks.  Need to be more thorough for
6836         # ZFS, since blocks are not allocated/returned to client immediately.
6837         sync_all_data
6838         wait_zfs_commit ost1 2
6839         cancel_lru_locks osc
6840         ls -ls $DIR/$tdir
6841
6842         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6843
6844         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6845
6846         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6847         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6848
6849         rm -f $DIR/$tdir/$tfile.[123]
6850 }
6851 run_test 56ab "lfs find --blocks"
6852
6853 test_56ba() {
6854         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6855                 skip "Need MDS version at least 2.10.50"
6856
6857         # Create composite files with one component
6858         local dir=$DIR/$tdir
6859
6860         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6861         # Create composite files with three components
6862         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6863         # Create non-composite files
6864         createmany -o $dir/${tfile}- 10
6865
6866         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6867
6868         [[ $nfiles == 10 ]] ||
6869                 error "lfs find -E 1M found $nfiles != 10 files"
6870
6871         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6872         [[ $nfiles == 25 ]] ||
6873                 error "lfs find ! -E 1M found $nfiles != 25 files"
6874
6875         # All files have a component that starts at 0
6876         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6877         [[ $nfiles == 35 ]] ||
6878                 error "lfs find --component-start 0 - $nfiles != 35 files"
6879
6880         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6881         [[ $nfiles == 15 ]] ||
6882                 error "lfs find --component-start 2M - $nfiles != 15 files"
6883
6884         # All files created here have a componenet that does not starts at 2M
6885         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6886         [[ $nfiles == 35 ]] ||
6887                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6888
6889         # Find files with a specified number of components
6890         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6891         [[ $nfiles == 15 ]] ||
6892                 error "lfs find --component-count 3 - $nfiles != 15 files"
6893
6894         # Remember non-composite files have a component count of zero
6895         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6896         [[ $nfiles == 10 ]] ||
6897                 error "lfs find --component-count 0 - $nfiles != 10 files"
6898
6899         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6900         [[ $nfiles == 20 ]] ||
6901                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6902
6903         # All files have a flag called "init"
6904         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6905         [[ $nfiles == 35 ]] ||
6906                 error "lfs find --component-flags init - $nfiles != 35 files"
6907
6908         # Multi-component files will have a component not initialized
6909         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6910         [[ $nfiles == 15 ]] ||
6911                 error "lfs find !--component-flags init - $nfiles != 15 files"
6912
6913         rm -rf $dir
6914
6915 }
6916 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6917
6918 test_56ca() {
6919         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6920                 skip "Need MDS version at least 2.10.57"
6921
6922         local td=$DIR/$tdir
6923         local tf=$td/$tfile
6924         local dir
6925         local nfiles
6926         local cmd
6927         local i
6928         local j
6929
6930         # create mirrored directories and mirrored files
6931         mkdir $td || error "mkdir $td failed"
6932         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6933         createmany -o $tf- 10 || error "create $tf- failed"
6934
6935         for i in $(seq 2); do
6936                 dir=$td/dir$i
6937                 mkdir $dir || error "mkdir $dir failed"
6938                 $LFS mirror create -N$((3 + i)) $dir ||
6939                         error "create mirrored dir $dir failed"
6940                 createmany -o $dir/$tfile- 10 ||
6941                         error "create $dir/$tfile- failed"
6942         done
6943
6944         # change the states of some mirrored files
6945         echo foo > $tf-6
6946         for i in $(seq 2); do
6947                 dir=$td/dir$i
6948                 for j in $(seq 4 9); do
6949                         echo foo > $dir/$tfile-$j
6950                 done
6951         done
6952
6953         # find mirrored files with specific mirror count
6954         cmd="$LFS find --mirror-count 3 --type f $td"
6955         nfiles=$($cmd | wc -l)
6956         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6957
6958         cmd="$LFS find ! --mirror-count 3 --type f $td"
6959         nfiles=$($cmd | wc -l)
6960         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6961
6962         cmd="$LFS find --mirror-count +2 --type f $td"
6963         nfiles=$($cmd | wc -l)
6964         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6965
6966         cmd="$LFS find --mirror-count -6 --type f $td"
6967         nfiles=$($cmd | wc -l)
6968         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6969
6970         # find mirrored files with specific file state
6971         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6972         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6973
6974         cmd="$LFS find --mirror-state=ro --type f $td"
6975         nfiles=$($cmd | wc -l)
6976         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6977
6978         cmd="$LFS find ! --mirror-state=ro --type f $td"
6979         nfiles=$($cmd | wc -l)
6980         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6981
6982         cmd="$LFS find --mirror-state=wp --type f $td"
6983         nfiles=$($cmd | wc -l)
6984         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6985
6986         cmd="$LFS find ! --mirror-state=sp --type f $td"
6987         nfiles=$($cmd | wc -l)
6988         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6989 }
6990 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6991
6992 test_57a() {
6993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6994         # note test will not do anything if MDS is not local
6995         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6996                 skip_env "ldiskfs only test"
6997         fi
6998         remote_mds_nodsh && skip "remote MDS with nodsh"
6999
7000         local MNTDEV="osd*.*MDT*.mntdev"
7001         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7002         [ -z "$DEV" ] && error "can't access $MNTDEV"
7003         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7004                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7005                         error "can't access $DEV"
7006                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7007                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7008                 rm $TMP/t57a.dump
7009         done
7010 }
7011 run_test 57a "verify MDS filesystem created with large inodes =="
7012
7013 test_57b() {
7014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7015         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7016                 skip_env "ldiskfs only test"
7017         fi
7018         remote_mds_nodsh && skip "remote MDS with nodsh"
7019
7020         local dir=$DIR/$tdir
7021         local filecount=100
7022         local file1=$dir/f1
7023         local fileN=$dir/f$filecount
7024
7025         rm -rf $dir || error "removing $dir"
7026         test_mkdir -c1 $dir
7027         local mdtidx=$($LFS getstripe -m $dir)
7028         local mdtname=MDT$(printf %04x $mdtidx)
7029         local facet=mds$((mdtidx + 1))
7030
7031         echo "mcreating $filecount files"
7032         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7033
7034         # verify that files do not have EAs yet
7035         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7036                 error "$file1 has an EA"
7037         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7038                 error "$fileN has an EA"
7039
7040         sync
7041         sleep 1
7042         df $dir  #make sure we get new statfs data
7043         local mdsfree=$(do_facet $facet \
7044                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7045         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7046         local file
7047
7048         echo "opening files to create objects/EAs"
7049         for file in $(seq -f $dir/f%g 1 $filecount); do
7050                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7051                         error "opening $file"
7052         done
7053
7054         # verify that files have EAs now
7055         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7056         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7057
7058         sleep 1  #make sure we get new statfs data
7059         df $dir
7060         local mdsfree2=$(do_facet $facet \
7061                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7062         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7063
7064         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7065                 if [ "$mdsfree" != "$mdsfree2" ]; then
7066                         error "MDC before $mdcfree != after $mdcfree2"
7067                 else
7068                         echo "MDC before $mdcfree != after $mdcfree2"
7069                         echo "unable to confirm if MDS has large inodes"
7070                 fi
7071         fi
7072         rm -rf $dir
7073 }
7074 run_test 57b "default LOV EAs are stored inside large inodes ==="
7075
7076 test_58() {
7077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7078         [ -z "$(which wiretest 2>/dev/null)" ] &&
7079                         skip_env "could not find wiretest"
7080
7081         wiretest
7082 }
7083 run_test 58 "verify cross-platform wire constants =============="
7084
7085 test_59() {
7086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7087
7088         echo "touch 130 files"
7089         createmany -o $DIR/f59- 130
7090         echo "rm 130 files"
7091         unlinkmany $DIR/f59- 130
7092         sync
7093         # wait for commitment of removal
7094         wait_delete_completed
7095 }
7096 run_test 59 "verify cancellation of llog records async ========="
7097
7098 TEST60_HEAD="test_60 run $RANDOM"
7099 test_60a() {
7100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7101         remote_mgs_nodsh && skip "remote MGS with nodsh"
7102         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7103                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7104                         skip_env "missing subtest run-llog.sh"
7105
7106         log "$TEST60_HEAD - from kernel mode"
7107         do_facet mgs "$LCTL dk > /dev/null"
7108         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7109         do_facet mgs $LCTL dk > $TMP/$tfile
7110
7111         # LU-6388: test llog_reader
7112         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7113         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7114         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7115                         skip_env "missing llog_reader"
7116         local fstype=$(facet_fstype mgs)
7117         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7118                 skip_env "Only for ldiskfs or zfs type mgs"
7119
7120         local mntpt=$(facet_mntpt mgs)
7121         local mgsdev=$(mgsdevname 1)
7122         local fid_list
7123         local fid
7124         local rec_list
7125         local rec
7126         local rec_type
7127         local obj_file
7128         local path
7129         local seq
7130         local oid
7131         local pass=true
7132
7133         #get fid and record list
7134         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7135                 tail -n 4))
7136         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7137                 tail -n 4))
7138         #remount mgs as ldiskfs or zfs type
7139         stop mgs || error "stop mgs failed"
7140         mount_fstype mgs || error "remount mgs failed"
7141         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7142                 fid=${fid_list[i]}
7143                 rec=${rec_list[i]}
7144                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7145                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7146                 oid=$((16#$oid))
7147
7148                 case $fstype in
7149                         ldiskfs )
7150                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7151                         zfs )
7152                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7153                 esac
7154                 echo "obj_file is $obj_file"
7155                 do_facet mgs $llog_reader $obj_file
7156
7157                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7158                         awk '{ print $3 }' | sed -e "s/^type=//g")
7159                 if [ $rec_type != $rec ]; then
7160                         echo "FAILED test_60a wrong record type $rec_type," \
7161                               "should be $rec"
7162                         pass=false
7163                         break
7164                 fi
7165
7166                 #check obj path if record type is LLOG_LOGID_MAGIC
7167                 if [ "$rec" == "1064553b" ]; then
7168                         path=$(do_facet mgs $llog_reader $obj_file |
7169                                 grep "path=" | awk '{ print $NF }' |
7170                                 sed -e "s/^path=//g")
7171                         if [ $obj_file != $mntpt/$path ]; then
7172                                 echo "FAILED test_60a wrong obj path" \
7173                                       "$montpt/$path, should be $obj_file"
7174                                 pass=false
7175                                 break
7176                         fi
7177                 fi
7178         done
7179         rm -f $TMP/$tfile
7180         #restart mgs before "error", otherwise it will block the next test
7181         stop mgs || error "stop mgs failed"
7182         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7183         $pass || error "test failed, see FAILED test_60a messages for specifics"
7184 }
7185 run_test 60a "llog_test run from kernel module and test llog_reader"
7186
7187 test_60b() { # bug 6411
7188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7189
7190         dmesg > $DIR/$tfile
7191         LLOG_COUNT=$(do_facet mgs dmesg |
7192                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7193                           /llog_[a-z]*.c:[0-9]/ {
7194                                 if (marker)
7195                                         from_marker++
7196                                 from_begin++
7197                           }
7198                           END {
7199                                 if (marker)
7200                                         print from_marker
7201                                 else
7202                                         print from_begin
7203                           }")
7204
7205         [[ $LLOG_COUNT -gt 120 ]] &&
7206                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7207 }
7208 run_test 60b "limit repeated messages from CERROR/CWARN"
7209
7210 test_60c() {
7211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7212
7213         echo "create 5000 files"
7214         createmany -o $DIR/f60c- 5000
7215 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7216         lctl set_param fail_loc=0x80000137
7217         unlinkmany $DIR/f60c- 5000
7218         lctl set_param fail_loc=0
7219 }
7220 run_test 60c "unlink file when mds full"
7221
7222 test_60d() {
7223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7224
7225         SAVEPRINTK=$(lctl get_param -n printk)
7226         # verify "lctl mark" is even working"
7227         MESSAGE="test message ID $RANDOM $$"
7228         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7229         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7230
7231         lctl set_param printk=0 || error "set lnet.printk failed"
7232         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7233         MESSAGE="new test message ID $RANDOM $$"
7234         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7235         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7236         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7237
7238         lctl set_param -n printk="$SAVEPRINTK"
7239 }
7240 run_test 60d "test printk console message masking"
7241
7242 test_60e() {
7243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7244         remote_mds_nodsh && skip "remote MDS with nodsh"
7245
7246         touch $DIR/$tfile
7247 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7248         do_facet mds1 lctl set_param fail_loc=0x15b
7249         rm $DIR/$tfile
7250 }
7251 run_test 60e "no space while new llog is being created"
7252
7253 test_60g() {
7254         local pid
7255         local i
7256
7257         test_mkdir -c $MDSCOUNT $DIR/$tdir
7258
7259         (
7260                 local index=0
7261                 while true; do
7262                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7263                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7264                                 2>/dev/null
7265                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7266                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7267                         index=$((index + 1))
7268                 done
7269         ) &
7270
7271         pid=$!
7272
7273         for i in {0..100}; do
7274                 # define OBD_FAIL_OSD_TXN_START    0x19a
7275                 local index=$((i % MDSCOUNT + 1))
7276
7277                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7278                         > /dev/null
7279                 usleep 100
7280         done
7281
7282         kill -9 $pid
7283
7284         for i in $(seq $MDSCOUNT); do
7285                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7286         done
7287
7288         mkdir $DIR/$tdir/new || error "mkdir failed"
7289         rmdir $DIR/$tdir/new || error "rmdir failed"
7290
7291         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7292                 -t namespace
7293         for i in $(seq $MDSCOUNT); do
7294                 wait_update_facet mds$i "$LCTL get_param -n \
7295                         mdd.$(facet_svc mds$i).lfsck_namespace |
7296                         awk '/^status/ { print \\\$2 }'" "completed"
7297         done
7298
7299         ls -R $DIR/$tdir || error "ls failed"
7300         rm -rf $DIR/$tdir || error "rmdir failed"
7301 }
7302 run_test 60g "transaction abort won't cause MDT hung"
7303
7304 test_60h() {
7305         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7306                 skip "Need MDS version at least 2.12.52"
7307         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7308
7309         local f
7310
7311         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7312         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7313         for fail_loc in 0x80000188 0x80000189; do
7314                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7315                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7316                         error "mkdir $dir-$fail_loc failed"
7317                 for i in {0..10}; do
7318                         # create may fail on missing stripe
7319                         echo $i > $DIR/$tdir-$fail_loc/$i
7320                 done
7321                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7322                         error "getdirstripe $tdir-$fail_loc failed"
7323                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7324                         error "migrate $tdir-$fail_loc failed"
7325                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7326                         error "getdirstripe $tdir-$fail_loc failed"
7327                 pushd $DIR/$tdir-$fail_loc
7328                 for f in *; do
7329                         echo $f | cmp $f - || error "$f data mismatch"
7330                 done
7331                 popd
7332                 rm -rf $DIR/$tdir-$fail_loc
7333         done
7334 }
7335 run_test 60h "striped directory with missing stripes can be accessed"
7336
7337 test_61a() {
7338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7339
7340         f="$DIR/f61"
7341         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7342         cancel_lru_locks osc
7343         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7344         sync
7345 }
7346 run_test 61a "mmap() writes don't make sync hang ================"
7347
7348 test_61b() {
7349         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7350 }
7351 run_test 61b "mmap() of unstriped file is successful"
7352
7353 # bug 2330 - insufficient obd_match error checking causes LBUG
7354 test_62() {
7355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7356
7357         f="$DIR/f62"
7358         echo foo > $f
7359         cancel_lru_locks osc
7360         lctl set_param fail_loc=0x405
7361         cat $f && error "cat succeeded, expect -EIO"
7362         lctl set_param fail_loc=0
7363 }
7364 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7365 # match every page all of the time.
7366 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7367
7368 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7369 # Though this test is irrelevant anymore, it helped to reveal some
7370 # other grant bugs (LU-4482), let's keep it.
7371 test_63a() {   # was test_63
7372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7373
7374         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7375
7376         for i in `seq 10` ; do
7377                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7378                 sleep 5
7379                 kill $!
7380                 sleep 1
7381         done
7382
7383         rm -f $DIR/f63 || true
7384 }
7385 run_test 63a "Verify oig_wait interruption does not crash ======="
7386
7387 # bug 2248 - async write errors didn't return to application on sync
7388 # bug 3677 - async write errors left page locked
7389 test_63b() {
7390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7391
7392         debugsave
7393         lctl set_param debug=-1
7394
7395         # ensure we have a grant to do async writes
7396         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7397         rm $DIR/$tfile
7398
7399         sync    # sync lest earlier test intercept the fail_loc
7400
7401         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7402         lctl set_param fail_loc=0x80000406
7403         $MULTIOP $DIR/$tfile Owy && \
7404                 error "sync didn't return ENOMEM"
7405         sync; sleep 2; sync     # do a real sync this time to flush page
7406         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7407                 error "locked page left in cache after async error" || true
7408         debugrestore
7409 }
7410 run_test 63b "async write errors should be returned to fsync ==="
7411
7412 test_64a () {
7413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7414
7415         df $DIR
7416         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7417 }
7418 run_test 64a "verify filter grant calculations (in kernel) ====="
7419
7420 test_64b () {
7421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7422
7423         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7424 }
7425 run_test 64b "check out-of-space detection on client"
7426
7427 test_64c() {
7428         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7429 }
7430 run_test 64c "verify grant shrink"
7431
7432 # this does exactly what osc_request.c:osc_announce_cached() does in
7433 # order to calculate max amount of grants to ask from server
7434 want_grant() {
7435         local tgt=$1
7436
7437         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7438         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7439
7440         ((rpc_in_flight ++));
7441         nrpages=$((nrpages * rpc_in_flight))
7442
7443         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7444
7445         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7446
7447         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7448         local undirty=$((nrpages * PAGE_SIZE))
7449
7450         local max_extent_pages
7451         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7452             grep grant_max_extent_size | awk '{print $2}')
7453         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7454         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7455         local grant_extent_tax
7456         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7457             grep grant_extent_tax | awk '{print $2}')
7458
7459         undirty=$((undirty + nrextents * grant_extent_tax))
7460
7461         echo $undirty
7462 }
7463
7464 # this is size of unit for grant allocation. It should be equal to
7465 # what tgt_grant.c:tgt_grant_chunk() calculates
7466 grant_chunk() {
7467         local tgt=$1
7468         local max_brw_size
7469         local grant_extent_tax
7470
7471         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7472             grep max_brw_size | awk '{print $2}')
7473
7474         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7475             grep grant_extent_tax | awk '{print $2}')
7476
7477         echo $(((max_brw_size + grant_extent_tax) * 2))
7478 }
7479
7480 test_64d() {
7481         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7482                 skip "OST < 2.10.55 doesn't limit grants enough"
7483
7484         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7485         local file=$DIR/$tfile
7486
7487         [[ $($LCTL get_param osc.${tgt}.import |
7488              grep "connect_flags:.*grant_param") ]] ||
7489                 skip "no grant_param connect flag"
7490
7491         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7492
7493         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7494
7495         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7496         stack_trap "rm -f $file" EXIT
7497
7498         $LFS setstripe $file -i 0 -c 1
7499         dd if=/dev/zero of=$file bs=1M count=1000 &
7500         ddpid=$!
7501
7502         while true
7503         do
7504                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7505                 if [[ $cur_grant -gt $max_cur_granted ]]
7506                 then
7507                         kill $ddpid
7508                         error "cur_grant $cur_grant > $max_cur_granted"
7509                 fi
7510                 kill -0 $ddpid
7511                 [[ $? -ne 0 ]] && break;
7512                 sleep 2
7513         done
7514
7515         rm -f $DIR/$tfile
7516         wait_delete_completed
7517         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7518 }
7519 run_test 64d "check grant limit exceed"
7520
7521 # bug 1414 - set/get directories' stripe info
7522 test_65a() {
7523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7524
7525         test_mkdir $DIR/$tdir
7526         touch $DIR/$tdir/f1
7527         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7528 }
7529 run_test 65a "directory with no stripe info"
7530
7531 test_65b() {
7532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7533
7534         test_mkdir $DIR/$tdir
7535         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7536
7537         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7538                                                 error "setstripe"
7539         touch $DIR/$tdir/f2
7540         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7541 }
7542 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7543
7544 test_65c() {
7545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7546         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7547
7548         test_mkdir $DIR/$tdir
7549         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7550
7551         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7552                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7553         touch $DIR/$tdir/f3
7554         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7555 }
7556 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7557
7558 test_65d() {
7559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7560
7561         test_mkdir $DIR/$tdir
7562         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7563         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7564
7565         if [[ $STRIPECOUNT -le 0 ]]; then
7566                 sc=1
7567         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7568                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7569                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7570         else
7571                 sc=$(($STRIPECOUNT - 1))
7572         fi
7573         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7574         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7575         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7576                 error "lverify failed"
7577 }
7578 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7579
7580 test_65e() {
7581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7582
7583         test_mkdir $DIR/$tdir
7584
7585         $LFS setstripe $DIR/$tdir || error "setstripe"
7586         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7587                                         error "no stripe info failed"
7588         touch $DIR/$tdir/f6
7589         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7590 }
7591 run_test 65e "directory setstripe defaults"
7592
7593 test_65f() {
7594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7595
7596         test_mkdir $DIR/${tdir}f
7597         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7598                 error "setstripe succeeded" || true
7599 }
7600 run_test 65f "dir setstripe permission (should return error) ==="
7601
7602 test_65g() {
7603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7604
7605         test_mkdir $DIR/$tdir
7606         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7607
7608         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7609                 error "setstripe -S failed"
7610         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7611         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7612                 error "delete default stripe failed"
7613 }
7614 run_test 65g "directory setstripe -d"
7615
7616 test_65h() {
7617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7618
7619         test_mkdir $DIR/$tdir
7620         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7621
7622         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7623                 error "setstripe -S failed"
7624         test_mkdir $DIR/$tdir/dd1
7625         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7626                 error "stripe info inherit failed"
7627 }
7628 run_test 65h "directory stripe info inherit ===================="
7629
7630 test_65i() {
7631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7632
7633         save_layout_restore_at_exit $MOUNT
7634
7635         # bug6367: set non-default striping on root directory
7636         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7637
7638         # bug12836: getstripe on -1 default directory striping
7639         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7640
7641         # bug12836: getstripe -v on -1 default directory striping
7642         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7643
7644         # bug12836: new find on -1 default directory striping
7645         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7646 }
7647 run_test 65i "various tests to set root directory striping"
7648
7649 test_65j() { # bug6367
7650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7651
7652         sync; sleep 1
7653
7654         # if we aren't already remounting for each test, do so for this test
7655         if [ "$I_MOUNTED" = "yes" ]; then
7656                 cleanup || error "failed to unmount"
7657                 setup
7658         fi
7659
7660         save_layout_restore_at_exit $MOUNT
7661
7662         $LFS setstripe -d $MOUNT || error "setstripe failed"
7663 }
7664 run_test 65j "set default striping on root directory (bug 6367)="
7665
7666 cleanup_65k() {
7667         rm -rf $DIR/$tdir
7668         wait_delete_completed
7669         do_facet $SINGLEMDS "lctl set_param -n \
7670                 osp.$ost*MDT0000.max_create_count=$max_count"
7671         do_facet $SINGLEMDS "lctl set_param -n \
7672                 osp.$ost*MDT0000.create_count=$count"
7673         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7674         echo $INACTIVE_OSC "is Activate"
7675
7676         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7677 }
7678
7679 test_65k() { # bug11679
7680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7681         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7682         remote_mds_nodsh && skip "remote MDS with nodsh"
7683
7684         local disable_precreate=true
7685         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7686                 disable_precreate=false
7687
7688         echo "Check OST status: "
7689         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7690                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7691
7692         for OSC in $MDS_OSCS; do
7693                 echo $OSC "is active"
7694                 do_facet $SINGLEMDS lctl --device %$OSC activate
7695         done
7696
7697         for INACTIVE_OSC in $MDS_OSCS; do
7698                 local ost=$(osc_to_ost $INACTIVE_OSC)
7699                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7700                                lov.*md*.target_obd |
7701                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7702
7703                 mkdir -p $DIR/$tdir
7704                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7705                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7706
7707                 echo "Deactivate: " $INACTIVE_OSC
7708                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7709
7710                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7711                               osp.$ost*MDT0000.create_count")
7712                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7713                                   osp.$ost*MDT0000.max_create_count")
7714                 $disable_precreate &&
7715                         do_facet $SINGLEMDS "lctl set_param -n \
7716                                 osp.$ost*MDT0000.max_create_count=0"
7717
7718                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7719                         [ -f $DIR/$tdir/$idx ] && continue
7720                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7721                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7722                                 { cleanup_65k;
7723                                   error "setstripe $idx should succeed"; }
7724                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7725                 done
7726                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7727                 rmdir $DIR/$tdir
7728
7729                 do_facet $SINGLEMDS "lctl set_param -n \
7730                         osp.$ost*MDT0000.max_create_count=$max_count"
7731                 do_facet $SINGLEMDS "lctl set_param -n \
7732                         osp.$ost*MDT0000.create_count=$count"
7733                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7734                 echo $INACTIVE_OSC "is Activate"
7735
7736                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7737         done
7738 }
7739 run_test 65k "validate manual striping works properly with deactivated OSCs"
7740
7741 test_65l() { # bug 12836
7742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7743
7744         test_mkdir -p $DIR/$tdir/test_dir
7745         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7746         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7747 }
7748 run_test 65l "lfs find on -1 stripe dir ========================"
7749
7750 test_65m() {
7751         local layout=$(save_layout $MOUNT)
7752         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7753                 restore_layout $MOUNT $layout
7754                 error "setstripe should fail by non-root users"
7755         }
7756         true
7757 }
7758 run_test 65m "normal user can't set filesystem default stripe"
7759
7760 test_65n() {
7761         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7762         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7763                 skip "Need MDS version at least 2.12.50"
7764         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7765
7766         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7767         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7768         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7769
7770         local root_layout=$(save_layout $MOUNT)
7771         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7772
7773         # new subdirectory under root directory should not inherit
7774         # the default layout from root
7775         local dir1=$MOUNT/$tdir-1
7776         mkdir $dir1 || error "mkdir $dir1 failed"
7777         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7778                 error "$dir1 shouldn't have LOV EA"
7779
7780         # delete the default layout on root directory
7781         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7782
7783         local dir2=$MOUNT/$tdir-2
7784         mkdir $dir2 || error "mkdir $dir2 failed"
7785         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7786                 error "$dir2 shouldn't have LOV EA"
7787
7788         # set a new striping pattern on root directory
7789         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7790         local new_def_stripe_size=$((def_stripe_size * 2))
7791         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7792                 error "set stripe size on $MOUNT failed"
7793
7794         # new file created in $dir2 should inherit the new stripe size from
7795         # the filesystem default
7796         local file2=$dir2/$tfile-2
7797         touch $file2 || error "touch $file2 failed"
7798
7799         local file2_stripe_size=$($LFS getstripe -S $file2)
7800         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7801                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7802
7803         local dir3=$MOUNT/$tdir-3
7804         mkdir $dir3 || error "mkdir $dir3 failed"
7805         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7806                 error "$dir3 shouldn't have LOV EA"
7807
7808         # set OST pool on root directory
7809         local pool=$TESTNAME
7810         pool_add $pool || error "add $pool failed"
7811         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7812                 error "add targets to $pool failed"
7813
7814         $LFS setstripe -p $pool $MOUNT ||
7815                 error "set OST pool on $MOUNT failed"
7816
7817         # new file created in $dir3 should inherit the pool from
7818         # the filesystem default
7819         local file3=$dir3/$tfile-3
7820         touch $file3 || error "touch $file3 failed"
7821
7822         local file3_pool=$($LFS getstripe -p $file3)
7823         [[ "$file3_pool" = "$pool" ]] ||
7824                 error "$file3 didn't inherit OST pool $pool"
7825
7826         local dir4=$MOUNT/$tdir-4
7827         mkdir $dir4 || error "mkdir $dir4 failed"
7828         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7829                 error "$dir4 shouldn't have LOV EA"
7830
7831         # new file created in $dir4 should inherit the pool from
7832         # the filesystem default
7833         local file4=$dir4/$tfile-4
7834         touch $file4 || error "touch $file4 failed"
7835
7836         local file4_pool=$($LFS getstripe -p $file4)
7837         [[ "$file4_pool" = "$pool" ]] ||
7838                 error "$file4 didn't inherit OST pool $pool"
7839
7840         # new subdirectory under non-root directory should inherit
7841         # the default layout from its parent directory
7842         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7843                 error "set directory layout on $dir4 failed"
7844
7845         local dir5=$dir4/$tdir-5
7846         mkdir $dir5 || error "mkdir $dir5 failed"
7847
7848         local dir4_layout=$(get_layout_param $dir4)
7849         local dir5_layout=$(get_layout_param $dir5)
7850         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7851                 error "$dir5 should inherit the default layout from $dir4"
7852
7853         # though subdir under ROOT doesn't inherit default layout, but
7854         # its sub dir/file should be created with default layout.
7855         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
7856         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
7857                 skip "Need MDS version at least 2.12.59"
7858
7859         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
7860         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
7861         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
7862
7863         if [ $default_lmv_hash == "none" ]; then
7864                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
7865         else
7866                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
7867                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
7868         fi
7869
7870         $LFS setdirstripe -D -c 2 $MOUNT ||
7871                 error "setdirstripe -D -c 2 failed"
7872         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
7873         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
7874         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
7875 }
7876 run_test 65n "don't inherit default layout from root for new subdirectories"
7877
7878 # bug 2543 - update blocks count on client
7879 test_66() {
7880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7881
7882         COUNT=${COUNT:-8}
7883         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7884         sync; sync_all_data; sync; sync_all_data
7885         cancel_lru_locks osc
7886         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7887         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7888 }
7889 run_test 66 "update inode blocks count on client ==============="
7890
7891 meminfo() {
7892         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7893 }
7894
7895 swap_used() {
7896         swapon -s | awk '($1 == "'$1'") { print $4 }'
7897 }
7898
7899 # bug5265, obdfilter oa2dentry return -ENOENT
7900 # #define OBD_FAIL_SRV_ENOENT 0x217
7901 test_69() {
7902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7903         remote_ost_nodsh && skip "remote OST with nodsh"
7904
7905         f="$DIR/$tfile"
7906         $LFS setstripe -c 1 -i 0 $f
7907
7908         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7909
7910         do_facet ost1 lctl set_param fail_loc=0x217
7911         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7912         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7913
7914         do_facet ost1 lctl set_param fail_loc=0
7915         $DIRECTIO write $f 0 2 || error "write error"
7916
7917         cancel_lru_locks osc
7918         $DIRECTIO read $f 0 1 || error "read error"
7919
7920         do_facet ost1 lctl set_param fail_loc=0x217
7921         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7922
7923         do_facet ost1 lctl set_param fail_loc=0
7924         rm -f $f
7925 }
7926 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7927
7928 test_71() {
7929         test_mkdir $DIR/$tdir
7930         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7931         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7932 }
7933 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7934
7935 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7937         [ "$RUNAS_ID" = "$UID" ] &&
7938                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7939         # Check that testing environment is properly set up. Skip if not
7940         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7941                 skip_env "User $RUNAS_ID does not exist - skipping"
7942
7943         touch $DIR/$tfile
7944         chmod 777 $DIR/$tfile
7945         chmod ug+s $DIR/$tfile
7946         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7947                 error "$RUNAS dd $DIR/$tfile failed"
7948         # See if we are still setuid/sgid
7949         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7950                 error "S/gid is not dropped on write"
7951         # Now test that MDS is updated too
7952         cancel_lru_locks mdc
7953         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7954                 error "S/gid is not dropped on MDS"
7955         rm -f $DIR/$tfile
7956 }
7957 run_test 72a "Test that remove suid works properly (bug5695) ===="
7958
7959 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7960         local perm
7961
7962         [ "$RUNAS_ID" = "$UID" ] &&
7963                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7964         [ "$RUNAS_ID" -eq 0 ] &&
7965                 skip_env "RUNAS_ID = 0 -- skipping"
7966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7967         # Check that testing environment is properly set up. Skip if not
7968         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7969                 skip_env "User $RUNAS_ID does not exist - skipping"
7970
7971         touch $DIR/${tfile}-f{g,u}
7972         test_mkdir $DIR/${tfile}-dg
7973         test_mkdir $DIR/${tfile}-du
7974         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7975         chmod g+s $DIR/${tfile}-{f,d}g
7976         chmod u+s $DIR/${tfile}-{f,d}u
7977         for perm in 777 2777 4777; do
7978                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7979                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7980                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7981                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7982         done
7983         true
7984 }
7985 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7986
7987 # bug 3462 - multiple simultaneous MDC requests
7988 test_73() {
7989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7990
7991         test_mkdir $DIR/d73-1
7992         test_mkdir $DIR/d73-2
7993         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7994         pid1=$!
7995
7996         lctl set_param fail_loc=0x80000129
7997         $MULTIOP $DIR/d73-1/f73-2 Oc &
7998         sleep 1
7999         lctl set_param fail_loc=0
8000
8001         $MULTIOP $DIR/d73-2/f73-3 Oc &
8002         pid3=$!
8003
8004         kill -USR1 $pid1
8005         wait $pid1 || return 1
8006
8007         sleep 25
8008
8009         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8010         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8011         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8012
8013         rm -rf $DIR/d73-*
8014 }
8015 run_test 73 "multiple MDC requests (should not deadlock)"
8016
8017 test_74a() { # bug 6149, 6184
8018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8019
8020         touch $DIR/f74a
8021         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8022         #
8023         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8024         # will spin in a tight reconnection loop
8025         $LCTL set_param fail_loc=0x8000030e
8026         # get any lock that won't be difficult - lookup works.
8027         ls $DIR/f74a
8028         $LCTL set_param fail_loc=0
8029         rm -f $DIR/f74a
8030         true
8031 }
8032 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8033
8034 test_74b() { # bug 13310
8035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8036
8037         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8038         #
8039         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8040         # will spin in a tight reconnection loop
8041         $LCTL set_param fail_loc=0x8000030e
8042         # get a "difficult" lock
8043         touch $DIR/f74b
8044         $LCTL set_param fail_loc=0
8045         rm -f $DIR/f74b
8046         true
8047 }
8048 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8049
8050 test_74c() {
8051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8052
8053         #define OBD_FAIL_LDLM_NEW_LOCK
8054         $LCTL set_param fail_loc=0x319
8055         touch $DIR/$tfile && error "touch successful"
8056         $LCTL set_param fail_loc=0
8057         true
8058 }
8059 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8060
8061 num_inodes() {
8062         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8063 }
8064
8065 test_76() { # Now for bug 20433, added originally in bug 1443
8066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8067
8068         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8069
8070         cancel_lru_locks osc
8071         BEFORE_INODES=$(num_inodes)
8072         echo "before inodes: $BEFORE_INODES"
8073         local COUNT=1000
8074         [ "$SLOW" = "no" ] && COUNT=100
8075         for i in $(seq $COUNT); do
8076                 touch $DIR/$tfile
8077                 rm -f $DIR/$tfile
8078         done
8079         cancel_lru_locks osc
8080         AFTER_INODES=$(num_inodes)
8081         echo "after inodes: $AFTER_INODES"
8082         local wait=0
8083         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
8084                 sleep 2
8085                 AFTER_INODES=$(num_inodes)
8086                 wait=$((wait+2))
8087                 echo "wait $wait seconds inodes: $AFTER_INODES"
8088                 if [ $wait -gt 30 ]; then
8089                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
8090                 fi
8091         done
8092 }
8093 run_test 76 "confirm clients recycle inodes properly ===="
8094
8095
8096 export ORIG_CSUM=""
8097 set_checksums()
8098 {
8099         # Note: in sptlrpc modes which enable its own bulk checksum, the
8100         # original crc32_le bulk checksum will be automatically disabled,
8101         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8102         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8103         # In this case set_checksums() will not be no-op, because sptlrpc
8104         # bulk checksum will be enabled all through the test.
8105
8106         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8107         lctl set_param -n osc.*.checksums $1
8108         return 0
8109 }
8110
8111 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8112                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8113 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8114                              tr -d [] | head -n1)}
8115 set_checksum_type()
8116 {
8117         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8118         rc=$?
8119         log "set checksum type to $1, rc = $rc"
8120         return $rc
8121 }
8122
8123 get_osc_checksum_type()
8124 {
8125         # arugment 1: OST name, like OST0000
8126         ost=$1
8127         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8128                         sed 's/.*\[\(.*\)\].*/\1/g')
8129         rc=$?
8130         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8131         echo $checksum_type
8132 }
8133
8134 F77_TMP=$TMP/f77-temp
8135 F77SZ=8
8136 setup_f77() {
8137         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8138                 error "error writing to $F77_TMP"
8139 }
8140
8141 test_77a() { # bug 10889
8142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8143         $GSS && skip_env "could not run with gss"
8144
8145         [ ! -f $F77_TMP ] && setup_f77
8146         set_checksums 1
8147         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8148         set_checksums 0
8149         rm -f $DIR/$tfile
8150 }
8151 run_test 77a "normal checksum read/write operation"
8152
8153 test_77b() { # bug 10889
8154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8155         $GSS && skip_env "could not run with gss"
8156
8157         [ ! -f $F77_TMP ] && setup_f77
8158         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8159         $LCTL set_param fail_loc=0x80000409
8160         set_checksums 1
8161
8162         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8163                 error "dd error: $?"
8164         $LCTL set_param fail_loc=0
8165
8166         for algo in $CKSUM_TYPES; do
8167                 cancel_lru_locks osc
8168                 set_checksum_type $algo
8169                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8170                 $LCTL set_param fail_loc=0x80000408
8171                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8172                 $LCTL set_param fail_loc=0
8173         done
8174         set_checksums 0
8175         set_checksum_type $ORIG_CSUM_TYPE
8176         rm -f $DIR/$tfile
8177 }
8178 run_test 77b "checksum error on client write, read"
8179
8180 cleanup_77c() {
8181         trap 0
8182         set_checksums 0
8183         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8184         $check_ost &&
8185                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8186         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8187         $check_ost && [ -n "$ost_file_prefix" ] &&
8188                 do_facet ost1 rm -f ${ost_file_prefix}\*
8189 }
8190
8191 test_77c() {
8192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8193         $GSS && skip_env "could not run with gss"
8194         remote_ost_nodsh && skip "remote OST with nodsh"
8195
8196         local bad1
8197         local osc_file_prefix
8198         local osc_file
8199         local check_ost=false
8200         local ost_file_prefix
8201         local ost_file
8202         local orig_cksum
8203         local dump_cksum
8204         local fid
8205
8206         # ensure corruption will occur on first OSS/OST
8207         $LFS setstripe -i 0 $DIR/$tfile
8208
8209         [ ! -f $F77_TMP ] && setup_f77
8210         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8211                 error "dd write error: $?"
8212         fid=$($LFS path2fid $DIR/$tfile)
8213
8214         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8215         then
8216                 check_ost=true
8217                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8218                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8219         else
8220                 echo "OSS do not support bulk pages dump upon error"
8221         fi
8222
8223         osc_file_prefix=$($LCTL get_param -n debug_path)
8224         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8225
8226         trap cleanup_77c EXIT
8227
8228         set_checksums 1
8229         # enable bulk pages dump upon error on Client
8230         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8231         # enable bulk pages dump upon error on OSS
8232         $check_ost &&
8233                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8234
8235         # flush Client cache to allow next read to reach OSS
8236         cancel_lru_locks osc
8237
8238         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8239         $LCTL set_param fail_loc=0x80000408
8240         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8241         $LCTL set_param fail_loc=0
8242
8243         rm -f $DIR/$tfile
8244
8245         # check cksum dump on Client
8246         osc_file=$(ls ${osc_file_prefix}*)
8247         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8248         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8249         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8250         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8251         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8252                      cksum)
8253         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8254         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8255                 error "dump content does not match on Client"
8256
8257         $check_ost || skip "No need to check cksum dump on OSS"
8258
8259         # check cksum dump on OSS
8260         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8261         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8262         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8263         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8264         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8265                 error "dump content does not match on OSS"
8266
8267         cleanup_77c
8268 }
8269 run_test 77c "checksum error on client read with debug"
8270
8271 test_77d() { # bug 10889
8272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8273         $GSS && skip_env "could not run with gss"
8274
8275         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8276         $LCTL set_param fail_loc=0x80000409
8277         set_checksums 1
8278         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8279                 error "direct write: rc=$?"
8280         $LCTL set_param fail_loc=0
8281         set_checksums 0
8282
8283         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8284         $LCTL set_param fail_loc=0x80000408
8285         set_checksums 1
8286         cancel_lru_locks osc
8287         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8288                 error "direct read: rc=$?"
8289         $LCTL set_param fail_loc=0
8290         set_checksums 0
8291 }
8292 run_test 77d "checksum error on OST direct write, read"
8293
8294 test_77f() { # bug 10889
8295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8296         $GSS && skip_env "could not run with gss"
8297
8298         set_checksums 1
8299         for algo in $CKSUM_TYPES; do
8300                 cancel_lru_locks osc
8301                 set_checksum_type $algo
8302                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8303                 $LCTL set_param fail_loc=0x409
8304                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8305                         error "direct write succeeded"
8306                 $LCTL set_param fail_loc=0
8307         done
8308         set_checksum_type $ORIG_CSUM_TYPE
8309         set_checksums 0
8310 }
8311 run_test 77f "repeat checksum error on write (expect error)"
8312
8313 test_77g() { # bug 10889
8314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8315         $GSS && skip_env "could not run with gss"
8316         remote_ost_nodsh && skip "remote OST with nodsh"
8317
8318         [ ! -f $F77_TMP ] && setup_f77
8319
8320         local file=$DIR/$tfile
8321         stack_trap "rm -f $file" EXIT
8322
8323         $LFS setstripe -c 1 -i 0 $file
8324         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8325         do_facet ost1 lctl set_param fail_loc=0x8000021a
8326         set_checksums 1
8327         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8328                 error "write error: rc=$?"
8329         do_facet ost1 lctl set_param fail_loc=0
8330         set_checksums 0
8331
8332         cancel_lru_locks osc
8333         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8334         do_facet ost1 lctl set_param fail_loc=0x8000021b
8335         set_checksums 1
8336         cmp $F77_TMP $file || error "file compare failed"
8337         do_facet ost1 lctl set_param fail_loc=0
8338         set_checksums 0
8339 }
8340 run_test 77g "checksum error on OST write, read"
8341
8342 test_77k() { # LU-10906
8343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8344         $GSS && skip_env "could not run with gss"
8345
8346         local cksum_param="osc.$FSNAME*.checksums"
8347         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8348         local checksum
8349         local i
8350
8351         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8352         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
8353         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
8354                 EXIT
8355
8356         for i in 0 1; do
8357                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8358                         error "failed to set checksum=$i on MGS"
8359                 wait_update $HOSTNAME "$get_checksum" $i
8360                 #remount
8361                 echo "remount client, checksum should be $i"
8362                 remount_client $MOUNT || error "failed to remount client"
8363                 checksum=$(eval $get_checksum)
8364                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8365         done
8366         # remove persistent param to avoid races with checksum mountopt below
8367         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8368                 error "failed to delete checksum on MGS"
8369
8370         for opt in "checksum" "nochecksum"; do
8371                 #remount with mount option
8372                 echo "remount client with option $opt, checksum should be $i"
8373                 umount_client $MOUNT || error "failed to umount client"
8374                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8375                         error "failed to mount client with option '$opt'"
8376                 checksum=$(eval $get_checksum)
8377                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8378                 i=$((i - 1))
8379         done
8380
8381         remount_client $MOUNT || error "failed to remount client"
8382 }
8383 run_test 77k "enable/disable checksum correctly"
8384
8385 test_77l() {
8386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8387         $GSS && skip_env "could not run with gss"
8388
8389         set_checksums 1
8390         stack_trap "set_checksums $ORIG_CSUM" EXIT
8391         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8392
8393         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8394
8395         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8396         for algo in $CKSUM_TYPES; do
8397                 set_checksum_type $algo || error "fail to set checksum type $algo"
8398                 osc_algo=$(get_osc_checksum_type OST0000)
8399                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8400
8401                 # no locks, no reqs to let the connection idle
8402                 cancel_lru_locks osc
8403                 lru_resize_disable osc
8404                 wait_osc_import_state client ost1 IDLE
8405
8406                 # ensure ost1 is connected
8407                 stat $DIR/$tfile >/dev/null || error "can't stat"
8408                 wait_osc_import_state client ost1 FULL
8409
8410                 osc_algo=$(get_osc_checksum_type OST0000)
8411                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8412         done
8413         return 0
8414 }
8415 run_test 77l "preferred checksum type is remembered after reconnected"
8416
8417 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8418 rm -f $F77_TMP
8419 unset F77_TMP
8420
8421 cleanup_test_78() {
8422         trap 0
8423         rm -f $DIR/$tfile
8424 }
8425
8426 test_78() { # bug 10901
8427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8428         remote_ost || skip_env "local OST"
8429
8430         NSEQ=5
8431         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8432         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8433         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8434         echo "MemTotal: $MEMTOTAL"
8435
8436         # reserve 256MB of memory for the kernel and other running processes,
8437         # and then take 1/2 of the remaining memory for the read/write buffers.
8438         if [ $MEMTOTAL -gt 512 ] ;then
8439                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8440         else
8441                 # for those poor memory-starved high-end clusters...
8442                 MEMTOTAL=$((MEMTOTAL / 2))
8443         fi
8444         echo "Mem to use for directio: $MEMTOTAL"
8445
8446         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8447         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8448         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8449         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8450                 head -n1)
8451         echo "Smallest OST: $SMALLESTOST"
8452         [[ $SMALLESTOST -lt 10240 ]] &&
8453                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8454
8455         trap cleanup_test_78 EXIT
8456
8457         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8458                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8459
8460         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8461         echo "File size: $F78SIZE"
8462         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8463         for i in $(seq 1 $NSEQ); do
8464                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8465                 echo directIO rdwr round $i of $NSEQ
8466                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8467         done
8468
8469         cleanup_test_78
8470 }
8471 run_test 78 "handle large O_DIRECT writes correctly ============"
8472
8473 test_79() { # bug 12743
8474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8475
8476         wait_delete_completed
8477
8478         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8479         BKFREE=$(calc_osc_kbytes kbytesfree)
8480         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8481
8482         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8483         DFTOTAL=`echo $STRING | cut -d, -f1`
8484         DFUSED=`echo $STRING  | cut -d, -f2`
8485         DFAVAIL=`echo $STRING | cut -d, -f3`
8486         DFFREE=$(($DFTOTAL - $DFUSED))
8487
8488         ALLOWANCE=$((64 * $OSTCOUNT))
8489
8490         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8491            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8492                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8493         fi
8494         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8495            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8496                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8497         fi
8498         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8499            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8500                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8501         fi
8502 }
8503 run_test 79 "df report consistency check ======================="
8504
8505 test_80() { # bug 10718
8506         remote_ost_nodsh && skip "remote OST with nodsh"
8507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8508
8509         # relax strong synchronous semantics for slow backends like ZFS
8510         local soc="obdfilter.*.sync_on_lock_cancel"
8511         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8512         local hosts=
8513         if [ "$soc_old" != "never" ] &&
8514                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8515                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8516                                 facet_active_host $host; done | sort -u)
8517                         do_nodes $hosts lctl set_param $soc=never
8518         fi
8519
8520         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8521         sync; sleep 1; sync
8522         local BEFORE=`date +%s`
8523         cancel_lru_locks osc
8524         local AFTER=`date +%s`
8525         local DIFF=$((AFTER-BEFORE))
8526         if [ $DIFF -gt 1 ] ; then
8527                 error "elapsed for 1M@1T = $DIFF"
8528         fi
8529
8530         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8531
8532         rm -f $DIR/$tfile
8533 }
8534 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8535
8536 test_81a() { # LU-456
8537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8538         remote_ost_nodsh && skip "remote OST with nodsh"
8539
8540         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8541         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8542         do_facet ost1 lctl set_param fail_loc=0x80000228
8543
8544         # write should trigger a retry and success
8545         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8546         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8547         RC=$?
8548         if [ $RC -ne 0 ] ; then
8549                 error "write should success, but failed for $RC"
8550         fi
8551 }
8552 run_test 81a "OST should retry write when get -ENOSPC ==============="
8553
8554 test_81b() { # LU-456
8555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8556         remote_ost_nodsh && skip "remote OST with nodsh"
8557
8558         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8559         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8560         do_facet ost1 lctl set_param fail_loc=0x228
8561
8562         # write should retry several times and return -ENOSPC finally
8563         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8564         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8565         RC=$?
8566         ENOSPC=28
8567         if [ $RC -ne $ENOSPC ] ; then
8568                 error "dd should fail for -ENOSPC, but succeed."
8569         fi
8570 }
8571 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8572
8573 test_82() { # LU-1031
8574         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8575         local gid1=14091995
8576         local gid2=16022000
8577
8578         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8579         local MULTIPID1=$!
8580         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8581         local MULTIPID2=$!
8582         kill -USR1 $MULTIPID2
8583         sleep 2
8584         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8585                 error "First grouplock does not block second one"
8586         else
8587                 echo "Second grouplock blocks first one"
8588         fi
8589         kill -USR1 $MULTIPID1
8590         wait $MULTIPID1
8591         wait $MULTIPID2
8592 }
8593 run_test 82 "Basic grouplock test"
8594
8595 test_99() {
8596         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8597
8598         test_mkdir $DIR/$tdir.cvsroot
8599         chown $RUNAS_ID $DIR/$tdir.cvsroot
8600
8601         cd $TMP
8602         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8603
8604         cd /etc/init.d
8605         # some versions of cvs import exit(1) when asked to import links or
8606         # files they can't read.  ignore those files.
8607         local toignore=$(find . -type l -printf '-I %f\n' -o \
8608                          ! -perm /4 -printf '-I %f\n')
8609         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8610                 $tdir.reposname vtag rtag
8611
8612         cd $DIR
8613         test_mkdir $DIR/$tdir.reposname
8614         chown $RUNAS_ID $DIR/$tdir.reposname
8615         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8616
8617         cd $DIR/$tdir.reposname
8618         $RUNAS touch foo99
8619         $RUNAS cvs add -m 'addmsg' foo99
8620         $RUNAS cvs update
8621         $RUNAS cvs commit -m 'nomsg' foo99
8622         rm -fr $DIR/$tdir.cvsroot
8623 }
8624 run_test 99 "cvs strange file/directory operations"
8625
8626 test_100() {
8627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8628         [[ "$NETTYPE" =~ tcp ]] ||
8629                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8630         remote_ost_nodsh && skip "remote OST with nodsh"
8631         remote_mds_nodsh && skip "remote MDS with nodsh"
8632         remote_servers ||
8633                 skip "useless for local single node setup"
8634
8635         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8636                 [ "$PROT" != "tcp" ] && continue
8637                 RPORT=$(echo $REMOTE | cut -d: -f2)
8638                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8639
8640                 rc=0
8641                 LPORT=`echo $LOCAL | cut -d: -f2`
8642                 if [ $LPORT -ge 1024 ]; then
8643                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8644                         netstat -tna
8645                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8646                 fi
8647         done
8648         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8649 }
8650 run_test 100 "check local port using privileged port ==========="
8651
8652 function get_named_value()
8653 {
8654     local tag
8655
8656     tag=$1
8657     while read ;do
8658         line=$REPLY
8659         case $line in
8660         $tag*)
8661             echo $line | sed "s/^$tag[ ]*//"
8662             break
8663             ;;
8664         esac
8665     done
8666 }
8667
8668 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8669                    awk '/^max_cached_mb/ { print $2 }')
8670
8671 cleanup_101a() {
8672         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8673         trap 0
8674 }
8675
8676 test_101a() {
8677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8678
8679         local s
8680         local discard
8681         local nreads=10000
8682         local cache_limit=32
8683
8684         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8685         trap cleanup_101a EXIT
8686         $LCTL set_param -n llite.*.read_ahead_stats 0
8687         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8688
8689         #
8690         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8691         #
8692         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8693         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8694
8695         discard=0
8696         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8697                 get_named_value 'read but discarded' | cut -d" " -f1); do
8698                         discard=$(($discard + $s))
8699         done
8700         cleanup_101a
8701
8702         $LCTL get_param osc.*-osc*.rpc_stats
8703         $LCTL get_param llite.*.read_ahead_stats
8704
8705         # Discard is generally zero, but sometimes a few random reads line up
8706         # and trigger larger readahead, which is wasted & leads to discards.
8707         if [[ $(($discard)) -gt $nreads ]]; then
8708                 error "too many ($discard) discarded pages"
8709         fi
8710         rm -f $DIR/$tfile || true
8711 }
8712 run_test 101a "check read-ahead for random reads"
8713
8714 setup_test101bc() {
8715         test_mkdir $DIR/$tdir
8716         local ssize=$1
8717         local FILE_LENGTH=$2
8718         STRIPE_OFFSET=0
8719
8720         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8721
8722         local list=$(comma_list $(osts_nodes))
8723         set_osd_param $list '' read_cache_enable 0
8724         set_osd_param $list '' writethrough_cache_enable 0
8725
8726         trap cleanup_test101bc EXIT
8727         # prepare the read-ahead file
8728         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8729
8730         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8731                                 count=$FILE_SIZE_MB 2> /dev/null
8732
8733 }
8734
8735 cleanup_test101bc() {
8736         trap 0
8737         rm -rf $DIR/$tdir
8738         rm -f $DIR/$tfile
8739
8740         local list=$(comma_list $(osts_nodes))
8741         set_osd_param $list '' read_cache_enable 1
8742         set_osd_param $list '' writethrough_cache_enable 1
8743 }
8744
8745 calc_total() {
8746         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8747 }
8748
8749 ra_check_101() {
8750         local READ_SIZE=$1
8751         local STRIPE_SIZE=$2
8752         local FILE_LENGTH=$3
8753         local RA_INC=1048576
8754         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8755         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8756                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8757         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8758                         get_named_value 'read but discarded' |
8759                         cut -d" " -f1 | calc_total)
8760         if [[ $DISCARD -gt $discard_limit ]]; then
8761                 $LCTL get_param llite.*.read_ahead_stats
8762                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8763         else
8764                 echo "Read-ahead success for size ${READ_SIZE}"
8765         fi
8766 }
8767
8768 test_101b() {
8769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8770         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8771
8772         local STRIPE_SIZE=1048576
8773         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8774
8775         if [ $SLOW == "yes" ]; then
8776                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8777         else
8778                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8779         fi
8780
8781         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8782
8783         # prepare the read-ahead file
8784         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8785         cancel_lru_locks osc
8786         for BIDX in 2 4 8 16 32 64 128 256
8787         do
8788                 local BSIZE=$((BIDX*4096))
8789                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8790                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8791                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8792                 $LCTL set_param -n llite.*.read_ahead_stats 0
8793                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8794                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8795                 cancel_lru_locks osc
8796                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8797         done
8798         cleanup_test101bc
8799         true
8800 }
8801 run_test 101b "check stride-io mode read-ahead ================="
8802
8803 test_101c() {
8804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8805
8806         local STRIPE_SIZE=1048576
8807         local FILE_LENGTH=$((STRIPE_SIZE*100))
8808         local nreads=10000
8809         local rsize=65536
8810         local osc_rpc_stats
8811
8812         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8813
8814         cancel_lru_locks osc
8815         $LCTL set_param osc.*.rpc_stats 0
8816         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8817         $LCTL get_param osc.*.rpc_stats
8818         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8819                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8820                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8821                 local size
8822
8823                 if [ $lines -le 20 ]; then
8824                         echo "continue debug"
8825                         continue
8826                 fi
8827                 for size in 1 2 4 8; do
8828                         local rpc=$(echo "$stats" |
8829                                     awk '($1 == "'$size':") {print $2; exit; }')
8830                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8831                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8832                 done
8833                 echo "$osc_rpc_stats check passed!"
8834         done
8835         cleanup_test101bc
8836         true
8837 }
8838 run_test 101c "check stripe_size aligned read-ahead ================="
8839
8840 set_read_ahead() {
8841         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8842         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8843 }
8844
8845 test_101d() {
8846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8847
8848         local file=$DIR/$tfile
8849         local sz_MB=${FILESIZE_101d:-500}
8850         local ra_MB=${READAHEAD_MB:-40}
8851
8852         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8853         [ $free_MB -lt $sz_MB ] &&
8854                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8855
8856         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8857         $LFS setstripe -c -1 $file || error "setstripe failed"
8858
8859         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8860         echo Cancel LRU locks on lustre client to flush the client cache
8861         cancel_lru_locks osc
8862
8863         echo Disable read-ahead
8864         local old_READAHEAD=$(set_read_ahead 0)
8865
8866         echo Reading the test file $file with read-ahead disabled
8867         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8868
8869         echo Cancel LRU locks on lustre client to flush the client cache
8870         cancel_lru_locks osc
8871         echo Enable read-ahead with ${ra_MB}MB
8872         set_read_ahead $ra_MB
8873
8874         echo Reading the test file $file with read-ahead enabled
8875         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8876
8877         echo "read-ahead disabled time read $raOFF"
8878         echo "read-ahead enabled  time read $raON"
8879
8880         set_read_ahead $old_READAHEAD
8881         rm -f $file
8882         wait_delete_completed
8883
8884         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8885                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8886 }
8887 run_test 101d "file read with and without read-ahead enabled"
8888
8889 test_101e() {
8890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8891
8892         local file=$DIR/$tfile
8893         local size_KB=500  #KB
8894         local count=100
8895         local bsize=1024
8896
8897         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8898         local need_KB=$((count * size_KB))
8899         [[ $free_KB -le $need_KB ]] &&
8900                 skip_env "Need free space $need_KB, have $free_KB"
8901
8902         echo "Creating $count ${size_KB}K test files"
8903         for ((i = 0; i < $count; i++)); do
8904                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8905         done
8906
8907         echo "Cancel LRU locks on lustre client to flush the client cache"
8908         cancel_lru_locks $OSC
8909
8910         echo "Reset readahead stats"
8911         $LCTL set_param -n llite.*.read_ahead_stats 0
8912
8913         for ((i = 0; i < $count; i++)); do
8914                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8915         done
8916
8917         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8918                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8919
8920         for ((i = 0; i < $count; i++)); do
8921                 rm -rf $file.$i 2>/dev/null
8922         done
8923
8924         #10000 means 20% reads are missing in readahead
8925         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8926 }
8927 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8928
8929 test_101f() {
8930         which iozone || skip_env "no iozone installed"
8931
8932         local old_debug=$($LCTL get_param debug)
8933         old_debug=${old_debug#*=}
8934         $LCTL set_param debug="reada mmap"
8935
8936         # create a test file
8937         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8938
8939         echo Cancel LRU locks on lustre client to flush the client cache
8940         cancel_lru_locks osc
8941
8942         echo Reset readahead stats
8943         $LCTL set_param -n llite.*.read_ahead_stats 0
8944
8945         echo mmap read the file with small block size
8946         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8947                 > /dev/null 2>&1
8948
8949         echo checking missing pages
8950         $LCTL get_param llite.*.read_ahead_stats
8951         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8952                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8953
8954         $LCTL set_param debug="$old_debug"
8955         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8956         rm -f $DIR/$tfile
8957 }
8958 run_test 101f "check mmap read performance"
8959
8960 test_101g_brw_size_test() {
8961         local mb=$1
8962         local pages=$((mb * 1048576 / PAGE_SIZE))
8963         local file=$DIR/$tfile
8964
8965         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8966                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8967         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8968                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8969                         return 2
8970         done
8971
8972         stack_trap "rm -f $file" EXIT
8973         $LCTL set_param -n osc.*.rpc_stats=0
8974
8975         # 10 RPCs should be enough for the test
8976         local count=10
8977         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8978                 { error "dd write ${mb} MB blocks failed"; return 3; }
8979         cancel_lru_locks osc
8980         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8981                 { error "dd write ${mb} MB blocks failed"; return 4; }
8982
8983         # calculate number of full-sized read and write RPCs
8984         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8985                 sed -n '/pages per rpc/,/^$/p' |
8986                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8987                 END { print reads,writes }'))
8988         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8989                 return 5
8990         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8991                 return 6
8992
8993         return 0
8994 }
8995
8996 test_101g() {
8997         remote_ost_nodsh && skip "remote OST with nodsh"
8998
8999         local rpcs
9000         local osts=$(get_facets OST)
9001         local list=$(comma_list $(osts_nodes))
9002         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9003         local brw_size="obdfilter.*.brw_size"
9004
9005         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9006
9007         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9008
9009         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9010                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9011                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9012            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9013                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9014                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9015
9016                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9017                         suffix="M"
9018
9019                 if [[ $orig_mb -lt 16 ]]; then
9020                         save_lustre_params $osts "$brw_size" > $p
9021                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9022                                 error "set 16MB RPC size failed"
9023
9024                         echo "remount client to enable new RPC size"
9025                         remount_client $MOUNT || error "remount_client failed"
9026                 fi
9027
9028                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9029                 # should be able to set brw_size=12, but no rpc_stats for that
9030                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9031         fi
9032
9033         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9034
9035         if [[ $orig_mb -lt 16 ]]; then
9036                 restore_lustre_params < $p
9037                 remount_client $MOUNT || error "remount_client restore failed"
9038         fi
9039
9040         rm -f $p $DIR/$tfile
9041 }
9042 run_test 101g "Big bulk(4/16 MiB) readahead"
9043
9044 test_101h() {
9045         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9046
9047         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9048                 error "dd 70M file failed"
9049         echo Cancel LRU locks on lustre client to flush the client cache
9050         cancel_lru_locks osc
9051
9052         echo "Reset readahead stats"
9053         $LCTL set_param -n llite.*.read_ahead_stats 0
9054
9055         echo "Read 10M of data but cross 64M bundary"
9056         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9057         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9058                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9059         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9060         rm -f $p $DIR/$tfile
9061 }
9062 run_test 101h "Readahead should cover current read window"
9063
9064 setup_test102() {
9065         test_mkdir $DIR/$tdir
9066         chown $RUNAS_ID $DIR/$tdir
9067         STRIPE_SIZE=65536
9068         STRIPE_OFFSET=1
9069         STRIPE_COUNT=$OSTCOUNT
9070         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9071
9072         trap cleanup_test102 EXIT
9073         cd $DIR
9074         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9075         cd $DIR/$tdir
9076         for num in 1 2 3 4; do
9077                 for count in $(seq 1 $STRIPE_COUNT); do
9078                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9079                                 local size=`expr $STRIPE_SIZE \* $num`
9080                                 local file=file"$num-$idx-$count"
9081                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9082                         done
9083                 done
9084         done
9085
9086         cd $DIR
9087         $1 tar cf $TMP/f102.tar $tdir --xattrs
9088 }
9089
9090 cleanup_test102() {
9091         trap 0
9092         rm -f $TMP/f102.tar
9093         rm -rf $DIR/d0.sanity/d102
9094 }
9095
9096 test_102a() {
9097         [ "$UID" != 0 ] && skip "must run as root"
9098         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9099                 skip_env "must have user_xattr"
9100
9101         [ -z "$(which setfattr 2>/dev/null)" ] &&
9102                 skip_env "could not find setfattr"
9103
9104         local testfile=$DIR/$tfile
9105
9106         touch $testfile
9107         echo "set/get xattr..."
9108         setfattr -n trusted.name1 -v value1 $testfile ||
9109                 error "setfattr -n trusted.name1=value1 $testfile failed"
9110         getfattr -n trusted.name1 $testfile 2> /dev/null |
9111           grep "trusted.name1=.value1" ||
9112                 error "$testfile missing trusted.name1=value1"
9113
9114         setfattr -n user.author1 -v author1 $testfile ||
9115                 error "setfattr -n user.author1=author1 $testfile failed"
9116         getfattr -n user.author1 $testfile 2> /dev/null |
9117           grep "user.author1=.author1" ||
9118                 error "$testfile missing trusted.author1=author1"
9119
9120         echo "listxattr..."
9121         setfattr -n trusted.name2 -v value2 $testfile ||
9122                 error "$testfile unable to set trusted.name2"
9123         setfattr -n trusted.name3 -v value3 $testfile ||
9124                 error "$testfile unable to set trusted.name3"
9125         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9126             grep "trusted.name" | wc -l) -eq 3 ] ||
9127                 error "$testfile missing 3 trusted.name xattrs"
9128
9129         setfattr -n user.author2 -v author2 $testfile ||
9130                 error "$testfile unable to set user.author2"
9131         setfattr -n user.author3 -v author3 $testfile ||
9132                 error "$testfile unable to set user.author3"
9133         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9134             grep "user.author" | wc -l) -eq 3 ] ||
9135                 error "$testfile missing 3 user.author xattrs"
9136
9137         echo "remove xattr..."
9138         setfattr -x trusted.name1 $testfile ||
9139                 error "$testfile error deleting trusted.name1"
9140         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9141                 error "$testfile did not delete trusted.name1 xattr"
9142
9143         setfattr -x user.author1 $testfile ||
9144                 error "$testfile error deleting user.author1"
9145         echo "set lustre special xattr ..."
9146         $LFS setstripe -c1 $testfile
9147         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9148                 awk -F "=" '/trusted.lov/ { print $2 }' )
9149         setfattr -n "trusted.lov" -v $lovea $testfile ||
9150                 error "$testfile doesn't ignore setting trusted.lov again"
9151         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9152                 error "$testfile allow setting invalid trusted.lov"
9153         rm -f $testfile
9154 }
9155 run_test 102a "user xattr test =================================="
9156
9157 test_102b() {
9158         [ -z "$(which setfattr 2>/dev/null)" ] &&
9159                 skip_env "could not find setfattr"
9160         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9161
9162         # b10930: get/set/list trusted.lov xattr
9163         echo "get/set/list trusted.lov xattr ..."
9164         local testfile=$DIR/$tfile
9165         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9166                 error "setstripe failed"
9167         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
9168                 error "getstripe failed"
9169         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
9170                 error "can't get trusted.lov from $testfile"
9171
9172         local testfile2=${testfile}2
9173         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
9174                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
9175
9176         $MCREATE $testfile2
9177         setfattr -n trusted.lov -v $value $testfile2
9178         local stripe_size=$($LFS getstripe -S $testfile2)
9179         local stripe_count=$($LFS getstripe -c $testfile2)
9180         [[ $stripe_size -eq 65536 ]] ||
9181                 error "stripe size $stripe_size != 65536"
9182         [[ $stripe_count -eq $STRIPECOUNT ]] ||
9183                 error "stripe count $stripe_count != $STRIPECOUNT"
9184         rm -f $DIR/$tfile
9185 }
9186 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
9187
9188 test_102c() {
9189         [ -z "$(which setfattr 2>/dev/null)" ] &&
9190                 skip_env "could not find setfattr"
9191         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9192
9193         # b10930: get/set/list lustre.lov xattr
9194         echo "get/set/list lustre.lov xattr ..."
9195         test_mkdir $DIR/$tdir
9196         chown $RUNAS_ID $DIR/$tdir
9197         local testfile=$DIR/$tdir/$tfile
9198         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9199                 error "setstripe failed"
9200         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9201                 error "getstripe failed"
9202         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9203         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9204
9205         local testfile2=${testfile}2
9206         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9207                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9208
9209         $RUNAS $MCREATE $testfile2
9210         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9211         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9212         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9213         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9214         [ $stripe_count -eq $STRIPECOUNT ] ||
9215                 error "stripe count $stripe_count != $STRIPECOUNT"
9216 }
9217 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9218
9219 compare_stripe_info1() {
9220         local stripe_index_all_zero=true
9221
9222         for num in 1 2 3 4; do
9223                 for count in $(seq 1 $STRIPE_COUNT); do
9224                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9225                                 local size=$((STRIPE_SIZE * num))
9226                                 local file=file"$num-$offset-$count"
9227                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9228                                 [[ $stripe_size -ne $size ]] &&
9229                                     error "$file: size $stripe_size != $size"
9230                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9231                                 # allow fewer stripes to be created, ORI-601
9232                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9233                                     error "$file: count $stripe_count != $count"
9234                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9235                                 [[ $stripe_index -ne 0 ]] &&
9236                                         stripe_index_all_zero=false
9237                         done
9238                 done
9239         done
9240         $stripe_index_all_zero &&
9241                 error "all files are being extracted starting from OST index 0"
9242         return 0
9243 }
9244
9245 have_xattrs_include() {
9246         tar --help | grep -q xattrs-include &&
9247                 echo --xattrs-include="lustre.*"
9248 }
9249
9250 test_102d() {
9251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9252         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9253
9254         XINC=$(have_xattrs_include)
9255         setup_test102
9256         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9257         cd $DIR/$tdir/$tdir
9258         compare_stripe_info1
9259 }
9260 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9261
9262 test_102f() {
9263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9264         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9265
9266         XINC=$(have_xattrs_include)
9267         setup_test102
9268         test_mkdir $DIR/$tdir.restore
9269         cd $DIR
9270         tar cf - --xattrs $tdir | tar xf - \
9271                 -C $DIR/$tdir.restore --xattrs $XINC
9272         cd $DIR/$tdir.restore/$tdir
9273         compare_stripe_info1
9274 }
9275 run_test 102f "tar copy files, not keep osts"
9276
9277 grow_xattr() {
9278         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9279                 skip "must have user_xattr"
9280         [ -z "$(which setfattr 2>/dev/null)" ] &&
9281                 skip_env "could not find setfattr"
9282         [ -z "$(which getfattr 2>/dev/null)" ] &&
9283                 skip_env "could not find getfattr"
9284
9285         local xsize=${1:-1024}  # in bytes
9286         local file=$DIR/$tfile
9287         local value="$(generate_string $xsize)"
9288         local xbig=trusted.big
9289         local toobig=$2
9290
9291         touch $file
9292         log "save $xbig on $file"
9293         if [ -z "$toobig" ]
9294         then
9295                 setfattr -n $xbig -v $value $file ||
9296                         error "saving $xbig on $file failed"
9297         else
9298                 setfattr -n $xbig -v $value $file &&
9299                         error "saving $xbig on $file succeeded"
9300                 return 0
9301         fi
9302
9303         local orig=$(get_xattr_value $xbig $file)
9304         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9305
9306         local xsml=trusted.sml
9307         log "save $xsml on $file"
9308         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9309
9310         local new=$(get_xattr_value $xbig $file)
9311         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9312
9313         log "grow $xsml on $file"
9314         setfattr -n $xsml -v "$value" $file ||
9315                 error "growing $xsml on $file failed"
9316
9317         new=$(get_xattr_value $xbig $file)
9318         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9319         log "$xbig still valid after growing $xsml"
9320
9321         rm -f $file
9322 }
9323
9324 test_102h() { # bug 15777
9325         grow_xattr 1024
9326 }
9327 run_test 102h "grow xattr from inside inode to external block"
9328
9329 test_102ha() {
9330         large_xattr_enabled || skip_env "ea_inode feature disabled"
9331
9332         echo "setting xattr of max xattr size: $(max_xattr_size)"
9333         grow_xattr $(max_xattr_size)
9334
9335         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9336         echo "This should fail:"
9337         grow_xattr $(($(max_xattr_size) + 10)) 1
9338 }
9339 run_test 102ha "grow xattr from inside inode to external inode"
9340
9341 test_102i() { # bug 17038
9342         [ -z "$(which getfattr 2>/dev/null)" ] &&
9343                 skip "could not find getfattr"
9344
9345         touch $DIR/$tfile
9346         ln -s $DIR/$tfile $DIR/${tfile}link
9347         getfattr -n trusted.lov $DIR/$tfile ||
9348                 error "lgetxattr on $DIR/$tfile failed"
9349         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9350                 grep -i "no such attr" ||
9351                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9352         rm -f $DIR/$tfile $DIR/${tfile}link
9353 }
9354 run_test 102i "lgetxattr test on symbolic link ============"
9355
9356 test_102j() {
9357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9358         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9359
9360         XINC=$(have_xattrs_include)
9361         setup_test102 "$RUNAS"
9362         chown $RUNAS_ID $DIR/$tdir
9363         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9364         cd $DIR/$tdir/$tdir
9365         compare_stripe_info1 "$RUNAS"
9366 }
9367 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9368
9369 test_102k() {
9370         [ -z "$(which setfattr 2>/dev/null)" ] &&
9371                 skip "could not find setfattr"
9372
9373         touch $DIR/$tfile
9374         # b22187 just check that does not crash for regular file.
9375         setfattr -n trusted.lov $DIR/$tfile
9376         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9377         local test_kdir=$DIR/$tdir
9378         test_mkdir $test_kdir
9379         local default_size=$($LFS getstripe -S $test_kdir)
9380         local default_count=$($LFS getstripe -c $test_kdir)
9381         local default_offset=$($LFS getstripe -i $test_kdir)
9382         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9383                 error 'dir setstripe failed'
9384         setfattr -n trusted.lov $test_kdir
9385         local stripe_size=$($LFS getstripe -S $test_kdir)
9386         local stripe_count=$($LFS getstripe -c $test_kdir)
9387         local stripe_offset=$($LFS getstripe -i $test_kdir)
9388         [ $stripe_size -eq $default_size ] ||
9389                 error "stripe size $stripe_size != $default_size"
9390         [ $stripe_count -eq $default_count ] ||
9391                 error "stripe count $stripe_count != $default_count"
9392         [ $stripe_offset -eq $default_offset ] ||
9393                 error "stripe offset $stripe_offset != $default_offset"
9394         rm -rf $DIR/$tfile $test_kdir
9395 }
9396 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
9397
9398 test_102l() {
9399         [ -z "$(which getfattr 2>/dev/null)" ] &&
9400                 skip "could not find getfattr"
9401
9402         # LU-532 trusted. xattr is invisible to non-root
9403         local testfile=$DIR/$tfile
9404
9405         touch $testfile
9406
9407         echo "listxattr as user..."
9408         chown $RUNAS_ID $testfile
9409         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
9410             grep -q "trusted" &&
9411                 error "$testfile trusted xattrs are user visible"
9412
9413         return 0;
9414 }
9415 run_test 102l "listxattr size test =================================="
9416
9417 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9418         local path=$DIR/$tfile
9419         touch $path
9420
9421         listxattr_size_check $path || error "listattr_size_check $path failed"
9422 }
9423 run_test 102m "Ensure listxattr fails on small bufffer ========"
9424
9425 cleanup_test102
9426
9427 getxattr() { # getxattr path name
9428         # Return the base64 encoding of the value of xattr name on path.
9429         local path=$1
9430         local name=$2
9431
9432         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9433         # file: $path
9434         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9435         #
9436         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9437
9438         getfattr --absolute-names --encoding=base64 --name=$name $path |
9439                 awk -F= -v name=$name '$1 == name {
9440                         print substr($0, index($0, "=") + 1);
9441         }'
9442 }
9443
9444 test_102n() { # LU-4101 mdt: protect internal xattrs
9445         [ -z "$(which setfattr 2>/dev/null)" ] &&
9446                 skip "could not find setfattr"
9447         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9448         then
9449                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9450         fi
9451
9452         local file0=$DIR/$tfile.0
9453         local file1=$DIR/$tfile.1
9454         local xattr0=$TMP/$tfile.0
9455         local xattr1=$TMP/$tfile.1
9456         local namelist="lov lma lmv link fid version som hsm"
9457         local name
9458         local value
9459
9460         rm -rf $file0 $file1 $xattr0 $xattr1
9461         touch $file0 $file1
9462
9463         # Get 'before' xattrs of $file1.
9464         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9465
9466         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9467                 namelist+=" lfsck_namespace"
9468         for name in $namelist; do
9469                 # Try to copy xattr from $file0 to $file1.
9470                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9471
9472                 setfattr --name=trusted.$name --value="$value" $file1 ||
9473                         error "setxattr 'trusted.$name' failed"
9474
9475                 # Try to set a garbage xattr.
9476                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9477
9478                 if [[ x$name == "xlov" ]]; then
9479                         setfattr --name=trusted.lov --value="$value" $file1 &&
9480                         error "setxattr invalid 'trusted.lov' success"
9481                 else
9482                         setfattr --name=trusted.$name --value="$value" $file1 ||
9483                                 error "setxattr invalid 'trusted.$name' failed"
9484                 fi
9485
9486                 # Try to remove the xattr from $file1. We don't care if this
9487                 # appears to succeed or fail, we just don't want there to be
9488                 # any changes or crashes.
9489                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9490         done
9491
9492         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9493         then
9494                 name="lfsck_ns"
9495                 # Try to copy xattr from $file0 to $file1.
9496                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9497
9498                 setfattr --name=trusted.$name --value="$value" $file1 ||
9499                         error "setxattr 'trusted.$name' failed"
9500
9501                 # Try to set a garbage xattr.
9502                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9503
9504                 setfattr --name=trusted.$name --value="$value" $file1 ||
9505                         error "setxattr 'trusted.$name' failed"
9506
9507                 # Try to remove the xattr from $file1. We don't care if this
9508                 # appears to succeed or fail, we just don't want there to be
9509                 # any changes or crashes.
9510                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9511         fi
9512
9513         # Get 'after' xattrs of file1.
9514         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9515
9516         if ! diff $xattr0 $xattr1; then
9517                 error "before and after xattrs of '$file1' differ"
9518         fi
9519
9520         rm -rf $file0 $file1 $xattr0 $xattr1
9521
9522         return 0
9523 }
9524 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9525
9526 test_102p() { # LU-4703 setxattr did not check ownership
9527         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9528                 skip "MDS needs to be at least 2.5.56"
9529
9530         local testfile=$DIR/$tfile
9531
9532         touch $testfile
9533
9534         echo "setfacl as user..."
9535         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9536         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9537
9538         echo "setfattr as user..."
9539         setfacl -m "u:$RUNAS_ID:---" $testfile
9540         $RUNAS setfattr -x system.posix_acl_access $testfile
9541         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9542 }
9543 run_test 102p "check setxattr(2) correctly fails without permission"
9544
9545 test_102q() {
9546         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9547                 skip "MDS needs to be at least 2.6.92"
9548
9549         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9550 }
9551 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9552
9553 test_102r() {
9554         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9555                 skip "MDS needs to be at least 2.6.93"
9556
9557         touch $DIR/$tfile || error "touch"
9558         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9559         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9560         rm $DIR/$tfile || error "rm"
9561
9562         #normal directory
9563         mkdir -p $DIR/$tdir || error "mkdir"
9564         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9565         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9566         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9567                 error "$testfile error deleting user.author1"
9568         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9569                 grep "user.$(basename $tdir)" &&
9570                 error "$tdir did not delete user.$(basename $tdir)"
9571         rmdir $DIR/$tdir || error "rmdir"
9572
9573         #striped directory
9574         test_mkdir $DIR/$tdir
9575         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9576         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9577         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9578                 error "$testfile error deleting user.author1"
9579         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9580                 grep "user.$(basename $tdir)" &&
9581                 error "$tdir did not delete user.$(basename $tdir)"
9582         rmdir $DIR/$tdir || error "rm striped dir"
9583 }
9584 run_test 102r "set EAs with empty values"
9585
9586 test_102s() {
9587         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9588                 skip "MDS needs to be at least 2.11.52"
9589
9590         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9591
9592         save_lustre_params client "llite.*.xattr_cache" > $save
9593
9594         for cache in 0 1; do
9595                 lctl set_param llite.*.xattr_cache=$cache
9596
9597                 rm -f $DIR/$tfile
9598                 touch $DIR/$tfile || error "touch"
9599                 for prefix in lustre security system trusted user; do
9600                         # Note getxattr() may fail with 'Operation not
9601                         # supported' or 'No such attribute' depending
9602                         # on prefix and cache.
9603                         getfattr -n $prefix.n102s $DIR/$tfile &&
9604                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9605                 done
9606         done
9607
9608         restore_lustre_params < $save
9609 }
9610 run_test 102s "getting nonexistent xattrs should fail"
9611
9612 test_102t() {
9613         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9614                 skip "MDS needs to be at least 2.11.52"
9615
9616         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9617
9618         save_lustre_params client "llite.*.xattr_cache" > $save
9619
9620         for cache in 0 1; do
9621                 lctl set_param llite.*.xattr_cache=$cache
9622
9623                 for buf_size in 0 256; do
9624                         rm -f $DIR/$tfile
9625                         touch $DIR/$tfile || error "touch"
9626                         setfattr -n user.multiop $DIR/$tfile
9627                         $MULTIOP $DIR/$tfile oa$buf_size ||
9628                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9629                 done
9630         done
9631
9632         restore_lustre_params < $save
9633 }
9634 run_test 102t "zero length xattr values handled correctly"
9635
9636 run_acl_subtest()
9637 {
9638     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9639     return $?
9640 }
9641
9642 test_103a() {
9643         [ "$UID" != 0 ] && skip "must run as root"
9644         $GSS && skip_env "could not run under gss"
9645         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9646                 skip_env "must have acl enabled"
9647         [ -z "$(which setfacl 2>/dev/null)" ] &&
9648                 skip_env "could not find setfacl"
9649         remote_mds_nodsh && skip "remote MDS with nodsh"
9650
9651         gpasswd -a daemon bin                           # LU-5641
9652         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9653
9654         declare -a identity_old
9655
9656         for num in $(seq $MDSCOUNT); do
9657                 switch_identity $num true || identity_old[$num]=$?
9658         done
9659
9660         SAVE_UMASK=$(umask)
9661         umask 0022
9662         mkdir -p $DIR/$tdir
9663         cd $DIR/$tdir
9664
9665         echo "performing cp ..."
9666         run_acl_subtest cp || error "run_acl_subtest cp failed"
9667         echo "performing getfacl-noacl..."
9668         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9669         echo "performing misc..."
9670         run_acl_subtest misc || error  "misc test failed"
9671         echo "performing permissions..."
9672         run_acl_subtest permissions || error "permissions failed"
9673         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9674         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9675                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9676                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9677         then
9678                 echo "performing permissions xattr..."
9679                 run_acl_subtest permissions_xattr ||
9680                         error "permissions_xattr failed"
9681         fi
9682         echo "performing setfacl..."
9683         run_acl_subtest setfacl || error  "setfacl test failed"
9684
9685         # inheritance test got from HP
9686         echo "performing inheritance..."
9687         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9688         chmod +x make-tree || error "chmod +x failed"
9689         run_acl_subtest inheritance || error "inheritance test failed"
9690         rm -f make-tree
9691
9692         echo "LU-974 ignore umask when acl is enabled..."
9693         run_acl_subtest 974 || error "LU-974 umask test failed"
9694         if [ $MDSCOUNT -ge 2 ]; then
9695                 run_acl_subtest 974_remote ||
9696                         error "LU-974 umask test failed under remote dir"
9697         fi
9698
9699         echo "LU-2561 newly created file is same size as directory..."
9700         if [ "$mds1_FSTYPE" != "zfs" ]; then
9701                 run_acl_subtest 2561 || error "LU-2561 test failed"
9702         else
9703                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9704         fi
9705
9706         run_acl_subtest 4924 || error "LU-4924 test failed"
9707
9708         cd $SAVE_PWD
9709         umask $SAVE_UMASK
9710
9711         for num in $(seq $MDSCOUNT); do
9712                 if [ "${identity_old[$num]}" = 1 ]; then
9713                         switch_identity $num false || identity_old[$num]=$?
9714                 fi
9715         done
9716 }
9717 run_test 103a "acl test"
9718
9719 test_103b() {
9720         declare -a pids
9721         local U
9722
9723         for U in {0..511}; do
9724                 {
9725                 local O=$(printf "%04o" $U)
9726
9727                 umask $(printf "%04o" $((511 ^ $O)))
9728                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9729                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9730
9731                 (( $S == ($O & 0666) )) ||
9732                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9733
9734                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9735                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9736                 (( $S == ($O & 0666) )) ||
9737                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9738
9739                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9740                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9741                 (( $S == ($O & 0666) )) ||
9742                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9743                 rm -f $DIR/$tfile.[smp]$0
9744                 } &
9745                 local pid=$!
9746
9747                 # limit the concurrently running threads to 64. LU-11878
9748                 local idx=$((U % 64))
9749                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9750                 pids[idx]=$pid
9751         done
9752         wait
9753 }
9754 run_test 103b "umask lfs setstripe"
9755
9756 test_103c() {
9757         mkdir -p $DIR/$tdir
9758         cp -rp $DIR/$tdir $DIR/$tdir.bak
9759
9760         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9761                 error "$DIR/$tdir shouldn't contain default ACL"
9762         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9763                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9764         true
9765 }
9766 run_test 103c "'cp -rp' won't set empty acl"
9767
9768 test_104a() {
9769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9770
9771         touch $DIR/$tfile
9772         lfs df || error "lfs df failed"
9773         lfs df -ih || error "lfs df -ih failed"
9774         lfs df -h $DIR || error "lfs df -h $DIR failed"
9775         lfs df -i $DIR || error "lfs df -i $DIR failed"
9776         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9777         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9778
9779         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9780         lctl --device %$OSC deactivate
9781         lfs df || error "lfs df with deactivated OSC failed"
9782         lctl --device %$OSC activate
9783         # wait the osc back to normal
9784         wait_osc_import_ready client ost
9785
9786         lfs df || error "lfs df with reactivated OSC failed"
9787         rm -f $DIR/$tfile
9788 }
9789 run_test 104a "lfs df [-ih] [path] test ========================="
9790
9791 test_104b() {
9792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9793         [ $RUNAS_ID -eq $UID ] &&
9794                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9795
9796         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9797                         grep "Permission denied" | wc -l)))
9798         if [ $denied_cnt -ne 0 ]; then
9799                 error "lfs check servers test failed"
9800         fi
9801 }
9802 run_test 104b "$RUNAS lfs check servers test ===================="
9803
9804 test_105a() {
9805         # doesn't work on 2.4 kernels
9806         touch $DIR/$tfile
9807         if $(flock_is_enabled); then
9808                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9809         else
9810                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9811         fi
9812         rm -f $DIR/$tfile
9813 }
9814 run_test 105a "flock when mounted without -o flock test ========"
9815
9816 test_105b() {
9817         touch $DIR/$tfile
9818         if $(flock_is_enabled); then
9819                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9820         else
9821                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9822         fi
9823         rm -f $DIR/$tfile
9824 }
9825 run_test 105b "fcntl when mounted without -o flock test ========"
9826
9827 test_105c() {
9828         touch $DIR/$tfile
9829         if $(flock_is_enabled); then
9830                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9831         else
9832                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9833         fi
9834         rm -f $DIR/$tfile
9835 }
9836 run_test 105c "lockf when mounted without -o flock test"
9837
9838 test_105d() { # bug 15924
9839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9840
9841         test_mkdir $DIR/$tdir
9842         flock_is_enabled || skip_env "mount w/o flock enabled"
9843         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9844         $LCTL set_param fail_loc=0x80000315
9845         flocks_test 2 $DIR/$tdir
9846 }
9847 run_test 105d "flock race (should not freeze) ========"
9848
9849 test_105e() { # bug 22660 && 22040
9850         flock_is_enabled || skip_env "mount w/o flock enabled"
9851
9852         touch $DIR/$tfile
9853         flocks_test 3 $DIR/$tfile
9854 }
9855 run_test 105e "Two conflicting flocks from same process"
9856
9857 test_106() { #bug 10921
9858         test_mkdir $DIR/$tdir
9859         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9860         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9861 }
9862 run_test 106 "attempt exec of dir followed by chown of that dir"
9863
9864 test_107() {
9865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9866
9867         CDIR=`pwd`
9868         local file=core
9869
9870         cd $DIR
9871         rm -f $file
9872
9873         local save_pattern=$(sysctl -n kernel.core_pattern)
9874         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9875         sysctl -w kernel.core_pattern=$file
9876         sysctl -w kernel.core_uses_pid=0
9877
9878         ulimit -c unlimited
9879         sleep 60 &
9880         SLEEPPID=$!
9881
9882         sleep 1
9883
9884         kill -s 11 $SLEEPPID
9885         wait $SLEEPPID
9886         if [ -e $file ]; then
9887                 size=`stat -c%s $file`
9888                 [ $size -eq 0 ] && error "Fail to create core file $file"
9889         else
9890                 error "Fail to create core file $file"
9891         fi
9892         rm -f $file
9893         sysctl -w kernel.core_pattern=$save_pattern
9894         sysctl -w kernel.core_uses_pid=$save_uses_pid
9895         cd $CDIR
9896 }
9897 run_test 107 "Coredump on SIG"
9898
9899 test_110() {
9900         test_mkdir $DIR/$tdir
9901         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9902         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9903                 error "mkdir with 256 char should fail, but did not"
9904         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9905                 error "create with 255 char failed"
9906         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9907                 error "create with 256 char should fail, but did not"
9908
9909         ls -l $DIR/$tdir
9910         rm -rf $DIR/$tdir
9911 }
9912 run_test 110 "filename length checking"
9913
9914 #
9915 # Purpose: To verify dynamic thread (OSS) creation.
9916 #
9917 test_115() {
9918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9919         remote_ost_nodsh && skip "remote OST with nodsh"
9920
9921         # Lustre does not stop service threads once they are started.
9922         # Reset number of running threads to default.
9923         stopall
9924         setupall
9925
9926         local OSTIO_pre
9927         local save_params="$TMP/sanity-$TESTNAME.parameters"
9928
9929         # Get ll_ost_io count before I/O
9930         OSTIO_pre=$(do_facet ost1 \
9931                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9932         # Exit if lustre is not running (ll_ost_io not running).
9933         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9934
9935         echo "Starting with $OSTIO_pre threads"
9936         local thread_max=$((OSTIO_pre * 2))
9937         local rpc_in_flight=$((thread_max * 2))
9938         # Number of I/O Process proposed to be started.
9939         local nfiles
9940         local facets=$(get_facets OST)
9941
9942         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9943         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9944
9945         # Set in_flight to $rpc_in_flight
9946         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9947                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9948         nfiles=${rpc_in_flight}
9949         # Set ost thread_max to $thread_max
9950         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9951
9952         # 5 Minutes should be sufficient for max number of OSS
9953         # threads(thread_max) to be created.
9954         local timeout=300
9955
9956         # Start I/O.
9957         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9958         test_mkdir $DIR/$tdir
9959         for i in $(seq $nfiles); do
9960                 local file=$DIR/$tdir/${tfile}-$i
9961                 $LFS setstripe -c -1 -i 0 $file
9962                 ($WTL $file $timeout)&
9963         done
9964
9965         # I/O Started - Wait for thread_started to reach thread_max or report
9966         # error if thread_started is more than thread_max.
9967         echo "Waiting for thread_started to reach thread_max"
9968         local thread_started=0
9969         local end_time=$((SECONDS + timeout))
9970
9971         while [ $SECONDS -le $end_time ] ; do
9972                 echo -n "."
9973                 # Get ost i/o thread_started count.
9974                 thread_started=$(do_facet ost1 \
9975                         "$LCTL get_param \
9976                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9977                 # Break out if thread_started is equal/greater than thread_max
9978                 if [[ $thread_started -ge $thread_max ]]; then
9979                         echo ll_ost_io thread_started $thread_started, \
9980                                 equal/greater than thread_max $thread_max
9981                         break
9982                 fi
9983                 sleep 1
9984         done
9985
9986         # Cleanup - We have the numbers, Kill i/o jobs if running.
9987         jobcount=($(jobs -p))
9988         for i in $(seq 0 $((${#jobcount[@]}-1)))
9989         do
9990                 kill -9 ${jobcount[$i]}
9991                 if [ $? -ne 0 ] ; then
9992                         echo Warning: \
9993                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9994                 fi
9995         done
9996
9997         # Cleanup files left by WTL binary.
9998         for i in $(seq $nfiles); do
9999                 local file=$DIR/$tdir/${tfile}-$i
10000                 rm -rf $file
10001                 if [ $? -ne 0 ] ; then
10002                         echo "Warning: Failed to delete file $file"
10003                 fi
10004         done
10005
10006         restore_lustre_params <$save_params
10007         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10008
10009         # Error out if no new thread has started or Thread started is greater
10010         # than thread max.
10011         if [[ $thread_started -le $OSTIO_pre ||
10012                         $thread_started -gt $thread_max ]]; then
10013                 error "ll_ost_io: thread_started $thread_started" \
10014                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10015                       "No new thread started or thread started greater " \
10016                       "than thread_max."
10017         fi
10018 }
10019 run_test 115 "verify dynamic thread creation===================="
10020
10021 free_min_max () {
10022         wait_delete_completed
10023         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10024         echo "OST kbytes available: ${AVAIL[@]}"
10025         MAXV=${AVAIL[0]}
10026         MAXI=0
10027         MINV=${AVAIL[0]}
10028         MINI=0
10029         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10030                 #echo OST $i: ${AVAIL[i]}kb
10031                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10032                         MAXV=${AVAIL[i]}
10033                         MAXI=$i
10034                 fi
10035                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10036                         MINV=${AVAIL[i]}
10037                         MINI=$i
10038                 fi
10039         done
10040         echo "Min free space: OST $MINI: $MINV"
10041         echo "Max free space: OST $MAXI: $MAXV"
10042 }
10043
10044 test_116a() { # was previously test_116()
10045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10046         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10047         remote_mds_nodsh && skip "remote MDS with nodsh"
10048
10049         echo -n "Free space priority "
10050         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10051                 head -n1
10052         declare -a AVAIL
10053         free_min_max
10054
10055         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10056         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10057         trap simple_cleanup_common EXIT
10058
10059         # Check if we need to generate uneven OSTs
10060         test_mkdir -p $DIR/$tdir/OST${MINI}
10061         local FILL=$((MINV / 4))
10062         local DIFF=$((MAXV - MINV))
10063         local DIFF2=$((DIFF * 100 / MINV))
10064
10065         local threshold=$(do_facet $SINGLEMDS \
10066                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10067         threshold=${threshold%%%}
10068         echo -n "Check for uneven OSTs: "
10069         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10070
10071         if [[ $DIFF2 -gt $threshold ]]; then
10072                 echo "ok"
10073                 echo "Don't need to fill OST$MINI"
10074         else
10075                 # generate uneven OSTs. Write 2% over the QOS threshold value
10076                 echo "no"
10077                 DIFF=$((threshold - DIFF2 + 2))
10078                 DIFF2=$((MINV * DIFF / 100))
10079                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10080                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10081                         error "setstripe failed"
10082                 DIFF=$((DIFF2 / 2048))
10083                 i=0
10084                 while [ $i -lt $DIFF ]; do
10085                         i=$((i + 1))
10086                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10087                                 bs=2M count=1 2>/dev/null
10088                         echo -n .
10089                 done
10090                 echo .
10091                 sync
10092                 sleep_maxage
10093                 free_min_max
10094         fi
10095
10096         DIFF=$((MAXV - MINV))
10097         DIFF2=$((DIFF * 100 / MINV))
10098         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10099         if [ $DIFF2 -gt $threshold ]; then
10100                 echo "ok"
10101         else
10102                 echo "failed - QOS mode won't be used"
10103                 simple_cleanup_common
10104                 skip "QOS imbalance criteria not met"
10105         fi
10106
10107         MINI1=$MINI
10108         MINV1=$MINV
10109         MAXI1=$MAXI
10110         MAXV1=$MAXV
10111
10112         # now fill using QOS
10113         $LFS setstripe -c 1 $DIR/$tdir
10114         FILL=$((FILL / 200))
10115         if [ $FILL -gt 600 ]; then
10116                 FILL=600
10117         fi
10118         echo "writing $FILL files to QOS-assigned OSTs"
10119         i=0
10120         while [ $i -lt $FILL ]; do
10121                 i=$((i + 1))
10122                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10123                         count=1 2>/dev/null
10124                 echo -n .
10125         done
10126         echo "wrote $i 200k files"
10127         sync
10128         sleep_maxage
10129
10130         echo "Note: free space may not be updated, so measurements might be off"
10131         free_min_max
10132         DIFF2=$((MAXV - MINV))
10133         echo "free space delta: orig $DIFF final $DIFF2"
10134         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10135         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10136         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10137         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10138         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10139         if [[ $DIFF -gt 0 ]]; then
10140                 FILL=$((DIFF2 * 100 / DIFF - 100))
10141                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10142         fi
10143
10144         # Figure out which files were written where
10145         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10146                awk '/'$MINI1': / {print $2; exit}')
10147         echo $UUID
10148         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10149         echo "$MINC files created on smaller OST $MINI1"
10150         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10151                awk '/'$MAXI1': / {print $2; exit}')
10152         echo $UUID
10153         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10154         echo "$MAXC files created on larger OST $MAXI1"
10155         if [[ $MINC -gt 0 ]]; then
10156                 FILL=$((MAXC * 100 / MINC - 100))
10157                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10158         fi
10159         [[ $MAXC -gt $MINC ]] ||
10160                 error_ignore LU-9 "stripe QOS didn't balance free space"
10161         simple_cleanup_common
10162 }
10163 run_test 116a "stripe QOS: free space balance ==================="
10164
10165 test_116b() { # LU-2093
10166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10167         remote_mds_nodsh && skip "remote MDS with nodsh"
10168
10169 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10170         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10171                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10172         [ -z "$old_rr" ] && skip "no QOS"
10173         do_facet $SINGLEMDS lctl set_param \
10174                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10175         mkdir -p $DIR/$tdir
10176         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10177         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10178         do_facet $SINGLEMDS lctl set_param fail_loc=0
10179         rm -rf $DIR/$tdir
10180         do_facet $SINGLEMDS lctl set_param \
10181                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10182 }
10183 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10184
10185 test_117() # bug 10891
10186 {
10187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10188
10189         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10190         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10191         lctl set_param fail_loc=0x21e
10192         > $DIR/$tfile || error "truncate failed"
10193         lctl set_param fail_loc=0
10194         echo "Truncate succeeded."
10195         rm -f $DIR/$tfile
10196 }
10197 run_test 117 "verify osd extend =========="
10198
10199 NO_SLOW_RESENDCOUNT=4
10200 export OLD_RESENDCOUNT=""
10201 set_resend_count () {
10202         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10203         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10204         lctl set_param -n $PROC_RESENDCOUNT $1
10205         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10206 }
10207
10208 # for reduce test_118* time (b=14842)
10209 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10210
10211 # Reset async IO behavior after error case
10212 reset_async() {
10213         FILE=$DIR/reset_async
10214
10215         # Ensure all OSCs are cleared
10216         $LFS setstripe -c -1 $FILE
10217         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10218         sync
10219         rm $FILE
10220 }
10221
10222 test_118a() #bug 11710
10223 {
10224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10225
10226         reset_async
10227
10228         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10229         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10230         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10231
10232         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10233                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10234                 return 1;
10235         fi
10236         rm -f $DIR/$tfile
10237 }
10238 run_test 118a "verify O_SYNC works =========="
10239
10240 test_118b()
10241 {
10242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10243         remote_ost_nodsh && skip "remote OST with nodsh"
10244
10245         reset_async
10246
10247         #define OBD_FAIL_SRV_ENOENT 0x217
10248         set_nodes_failloc "$(osts_nodes)" 0x217
10249         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10250         RC=$?
10251         set_nodes_failloc "$(osts_nodes)" 0
10252         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10253         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10254                     grep -c writeback)
10255
10256         if [[ $RC -eq 0 ]]; then
10257                 error "Must return error due to dropped pages, rc=$RC"
10258                 return 1;
10259         fi
10260
10261         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10262                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10263                 return 1;
10264         fi
10265
10266         echo "Dirty pages not leaked on ENOENT"
10267
10268         # Due to the above error the OSC will issue all RPCs syncronously
10269         # until a subsequent RPC completes successfully without error.
10270         $MULTIOP $DIR/$tfile Ow4096yc
10271         rm -f $DIR/$tfile
10272
10273         return 0
10274 }
10275 run_test 118b "Reclaim dirty pages on fatal error =========="
10276
10277 test_118c()
10278 {
10279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10280
10281         # for 118c, restore the original resend count, LU-1940
10282         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10283                                 set_resend_count $OLD_RESENDCOUNT
10284         remote_ost_nodsh && skip "remote OST with nodsh"
10285
10286         reset_async
10287
10288         #define OBD_FAIL_OST_EROFS               0x216
10289         set_nodes_failloc "$(osts_nodes)" 0x216
10290
10291         # multiop should block due to fsync until pages are written
10292         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10293         MULTIPID=$!
10294         sleep 1
10295
10296         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10297                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10298         fi
10299
10300         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10301                     grep -c writeback)
10302         if [[ $WRITEBACK -eq 0 ]]; then
10303                 error "No page in writeback, writeback=$WRITEBACK"
10304         fi
10305
10306         set_nodes_failloc "$(osts_nodes)" 0
10307         wait $MULTIPID
10308         RC=$?
10309         if [[ $RC -ne 0 ]]; then
10310                 error "Multiop fsync failed, rc=$RC"
10311         fi
10312
10313         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10314         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10315                     grep -c writeback)
10316         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10317                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10318         fi
10319
10320         rm -f $DIR/$tfile
10321         echo "Dirty pages flushed via fsync on EROFS"
10322         return 0
10323 }
10324 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10325
10326 # continue to use small resend count to reduce test_118* time (b=14842)
10327 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10328
10329 test_118d()
10330 {
10331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10332         remote_ost_nodsh && skip "remote OST with nodsh"
10333
10334         reset_async
10335
10336         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10337         set_nodes_failloc "$(osts_nodes)" 0x214
10338         # multiop should block due to fsync until pages are written
10339         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10340         MULTIPID=$!
10341         sleep 1
10342
10343         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10344                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10345         fi
10346
10347         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10348                     grep -c writeback)
10349         if [[ $WRITEBACK -eq 0 ]]; then
10350                 error "No page in writeback, writeback=$WRITEBACK"
10351         fi
10352
10353         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10354         set_nodes_failloc "$(osts_nodes)" 0
10355
10356         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10357         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10358                     grep -c writeback)
10359         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10360                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10361         fi
10362
10363         rm -f $DIR/$tfile
10364         echo "Dirty pages gaurenteed flushed via fsync"
10365         return 0
10366 }
10367 run_test 118d "Fsync validation inject a delay of the bulk =========="
10368
10369 test_118f() {
10370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10371
10372         reset_async
10373
10374         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10375         lctl set_param fail_loc=0x8000040a
10376
10377         # Should simulate EINVAL error which is fatal
10378         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10379         RC=$?
10380         if [[ $RC -eq 0 ]]; then
10381                 error "Must return error due to dropped pages, rc=$RC"
10382         fi
10383
10384         lctl set_param fail_loc=0x0
10385
10386         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10387         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10388         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10389                     grep -c writeback)
10390         if [[ $LOCKED -ne 0 ]]; then
10391                 error "Locked pages remain in cache, locked=$LOCKED"
10392         fi
10393
10394         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10395                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10396         fi
10397
10398         rm -f $DIR/$tfile
10399         echo "No pages locked after fsync"
10400
10401         reset_async
10402         return 0
10403 }
10404 run_test 118f "Simulate unrecoverable OSC side error =========="
10405
10406 test_118g() {
10407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10408
10409         reset_async
10410
10411         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
10412         lctl set_param fail_loc=0x406
10413
10414         # simulate local -ENOMEM
10415         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10416         RC=$?
10417
10418         lctl set_param fail_loc=0
10419         if [[ $RC -eq 0 ]]; then
10420                 error "Must return error due to dropped pages, rc=$RC"
10421         fi
10422
10423         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10424         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10425         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10426                         grep -c writeback)
10427         if [[ $LOCKED -ne 0 ]]; then
10428                 error "Locked pages remain in cache, locked=$LOCKED"
10429         fi
10430
10431         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10432                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10433         fi
10434
10435         rm -f $DIR/$tfile
10436         echo "No pages locked after fsync"
10437
10438         reset_async
10439         return 0
10440 }
10441 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10442
10443 test_118h() {
10444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10445         remote_ost_nodsh && skip "remote OST with nodsh"
10446
10447         reset_async
10448
10449         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10450         set_nodes_failloc "$(osts_nodes)" 0x20e
10451         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10452         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10453         RC=$?
10454
10455         set_nodes_failloc "$(osts_nodes)" 0
10456         if [[ $RC -eq 0 ]]; then
10457                 error "Must return error due to dropped pages, rc=$RC"
10458         fi
10459
10460         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10461         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10462         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10463                     grep -c writeback)
10464         if [[ $LOCKED -ne 0 ]]; then
10465                 error "Locked pages remain in cache, locked=$LOCKED"
10466         fi
10467
10468         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10469                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10470         fi
10471
10472         rm -f $DIR/$tfile
10473         echo "No pages locked after fsync"
10474
10475         return 0
10476 }
10477 run_test 118h "Verify timeout in handling recoverables errors  =========="
10478
10479 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10480
10481 test_118i() {
10482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10483         remote_ost_nodsh && skip "remote OST with nodsh"
10484
10485         reset_async
10486
10487         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10488         set_nodes_failloc "$(osts_nodes)" 0x20e
10489
10490         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10491         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10492         PID=$!
10493         sleep 5
10494         set_nodes_failloc "$(osts_nodes)" 0
10495
10496         wait $PID
10497         RC=$?
10498         if [[ $RC -ne 0 ]]; then
10499                 error "got error, but should be not, rc=$RC"
10500         fi
10501
10502         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10503         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10504         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10505         if [[ $LOCKED -ne 0 ]]; then
10506                 error "Locked pages remain in cache, locked=$LOCKED"
10507         fi
10508
10509         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10510                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10511         fi
10512
10513         rm -f $DIR/$tfile
10514         echo "No pages locked after fsync"
10515
10516         return 0
10517 }
10518 run_test 118i "Fix error before timeout in recoverable error  =========="
10519
10520 [ "$SLOW" = "no" ] && set_resend_count 4
10521
10522 test_118j() {
10523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10524         remote_ost_nodsh && skip "remote OST with nodsh"
10525
10526         reset_async
10527
10528         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10529         set_nodes_failloc "$(osts_nodes)" 0x220
10530
10531         # return -EIO from OST
10532         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10533         RC=$?
10534         set_nodes_failloc "$(osts_nodes)" 0x0
10535         if [[ $RC -eq 0 ]]; then
10536                 error "Must return error due to dropped pages, rc=$RC"
10537         fi
10538
10539         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10540         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10541         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10542         if [[ $LOCKED -ne 0 ]]; then
10543                 error "Locked pages remain in cache, locked=$LOCKED"
10544         fi
10545
10546         # in recoverable error on OST we want resend and stay until it finished
10547         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10548                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10549         fi
10550
10551         rm -f $DIR/$tfile
10552         echo "No pages locked after fsync"
10553
10554         return 0
10555 }
10556 run_test 118j "Simulate unrecoverable OST side error =========="
10557
10558 test_118k()
10559 {
10560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10561         remote_ost_nodsh && skip "remote OSTs with nodsh"
10562
10563         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10564         set_nodes_failloc "$(osts_nodes)" 0x20e
10565         test_mkdir $DIR/$tdir
10566
10567         for ((i=0;i<10;i++)); do
10568                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10569                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10570                 SLEEPPID=$!
10571                 sleep 0.500s
10572                 kill $SLEEPPID
10573                 wait $SLEEPPID
10574         done
10575
10576         set_nodes_failloc "$(osts_nodes)" 0
10577         rm -rf $DIR/$tdir
10578 }
10579 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10580
10581 test_118l() # LU-646
10582 {
10583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10584
10585         test_mkdir $DIR/$tdir
10586         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10587         rm -rf $DIR/$tdir
10588 }
10589 run_test 118l "fsync dir"
10590
10591 test_118m() # LU-3066
10592 {
10593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10594
10595         test_mkdir $DIR/$tdir
10596         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10597         rm -rf $DIR/$tdir
10598 }
10599 run_test 118m "fdatasync dir ========="
10600
10601 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10602
10603 test_118n()
10604 {
10605         local begin
10606         local end
10607
10608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10609         remote_ost_nodsh && skip "remote OSTs with nodsh"
10610
10611         # Sleep to avoid a cached response.
10612         #define OBD_STATFS_CACHE_SECONDS 1
10613         sleep 2
10614
10615         # Inject a 10 second delay in the OST_STATFS handler.
10616         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10617         set_nodes_failloc "$(osts_nodes)" 0x242
10618
10619         begin=$SECONDS
10620         stat --file-system $MOUNT > /dev/null
10621         end=$SECONDS
10622
10623         set_nodes_failloc "$(osts_nodes)" 0
10624
10625         if ((end - begin > 20)); then
10626             error "statfs took $((end - begin)) seconds, expected 10"
10627         fi
10628 }
10629 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10630
10631 test_119a() # bug 11737
10632 {
10633         BSIZE=$((512 * 1024))
10634         directio write $DIR/$tfile 0 1 $BSIZE
10635         # We ask to read two blocks, which is more than a file size.
10636         # directio will indicate an error when requested and actual
10637         # sizes aren't equeal (a normal situation in this case) and
10638         # print actual read amount.
10639         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10640         if [ "$NOB" != "$BSIZE" ]; then
10641                 error "read $NOB bytes instead of $BSIZE"
10642         fi
10643         rm -f $DIR/$tfile
10644 }
10645 run_test 119a "Short directIO read must return actual read amount"
10646
10647 test_119b() # bug 11737
10648 {
10649         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10650
10651         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10652         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10653         sync
10654         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10655                 error "direct read failed"
10656         rm -f $DIR/$tfile
10657 }
10658 run_test 119b "Sparse directIO read must return actual read amount"
10659
10660 test_119c() # bug 13099
10661 {
10662         BSIZE=1048576
10663         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10664         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10665         rm -f $DIR/$tfile
10666 }
10667 run_test 119c "Testing for direct read hitting hole"
10668
10669 test_119d() # bug 15950
10670 {
10671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10672
10673         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10674         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10675         BSIZE=1048576
10676         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10677         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10678         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10679         lctl set_param fail_loc=0x40d
10680         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10681         pid_dio=$!
10682         sleep 1
10683         cat $DIR/$tfile > /dev/null &
10684         lctl set_param fail_loc=0
10685         pid_reads=$!
10686         wait $pid_dio
10687         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10688         sleep 2
10689         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10690         error "the read rpcs have not completed in 2s"
10691         rm -f $DIR/$tfile
10692         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10693 }
10694 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10695
10696 test_120a() {
10697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10698         remote_mds_nodsh && skip "remote MDS with nodsh"
10699         test_mkdir -i0 -c1 $DIR/$tdir
10700         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10701                 skip_env "no early lock cancel on server"
10702
10703         lru_resize_disable mdc
10704         lru_resize_disable osc
10705         cancel_lru_locks mdc
10706         # asynchronous object destroy at MDT could cause bl ast to client
10707         cancel_lru_locks osc
10708
10709         stat $DIR/$tdir > /dev/null
10710         can1=$(do_facet mds1 \
10711                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10712                awk '/ldlm_cancel/ {print $2}')
10713         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10714                awk '/ldlm_bl_callback/ {print $2}')
10715         test_mkdir -i0 -c1 $DIR/$tdir/d1
10716         can2=$(do_facet mds1 \
10717                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10718                awk '/ldlm_cancel/ {print $2}')
10719         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10720                awk '/ldlm_bl_callback/ {print $2}')
10721         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10722         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10723         lru_resize_enable mdc
10724         lru_resize_enable osc
10725 }
10726 run_test 120a "Early Lock Cancel: mkdir test"
10727
10728 test_120b() {
10729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10730         remote_mds_nodsh && skip "remote MDS with nodsh"
10731         test_mkdir $DIR/$tdir
10732         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10733                 skip_env "no early lock cancel on server"
10734
10735         lru_resize_disable mdc
10736         lru_resize_disable osc
10737         cancel_lru_locks mdc
10738         stat $DIR/$tdir > /dev/null
10739         can1=$(do_facet $SINGLEMDS \
10740                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10741                awk '/ldlm_cancel/ {print $2}')
10742         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10743                awk '/ldlm_bl_callback/ {print $2}')
10744         touch $DIR/$tdir/f1
10745         can2=$(do_facet $SINGLEMDS \
10746                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10747                awk '/ldlm_cancel/ {print $2}')
10748         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10749                awk '/ldlm_bl_callback/ {print $2}')
10750         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10751         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10752         lru_resize_enable mdc
10753         lru_resize_enable osc
10754 }
10755 run_test 120b "Early Lock Cancel: create test"
10756
10757 test_120c() {
10758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10759         remote_mds_nodsh && skip "remote MDS with nodsh"
10760         test_mkdir -i0 -c1 $DIR/$tdir
10761         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10762                 skip "no early lock cancel on server"
10763
10764         lru_resize_disable mdc
10765         lru_resize_disable osc
10766         test_mkdir -i0 -c1 $DIR/$tdir/d1
10767         test_mkdir -i0 -c1 $DIR/$tdir/d2
10768         touch $DIR/$tdir/d1/f1
10769         cancel_lru_locks mdc
10770         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10771         can1=$(do_facet mds1 \
10772                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10773                awk '/ldlm_cancel/ {print $2}')
10774         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10775                awk '/ldlm_bl_callback/ {print $2}')
10776         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10777         can2=$(do_facet mds1 \
10778                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10779                awk '/ldlm_cancel/ {print $2}')
10780         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10781                awk '/ldlm_bl_callback/ {print $2}')
10782         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10783         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10784         lru_resize_enable mdc
10785         lru_resize_enable osc
10786 }
10787 run_test 120c "Early Lock Cancel: link test"
10788
10789 test_120d() {
10790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10791         remote_mds_nodsh && skip "remote MDS with nodsh"
10792         test_mkdir -i0 -c1 $DIR/$tdir
10793         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10794                 skip_env "no early lock cancel on server"
10795
10796         lru_resize_disable mdc
10797         lru_resize_disable osc
10798         touch $DIR/$tdir
10799         cancel_lru_locks mdc
10800         stat $DIR/$tdir > /dev/null
10801         can1=$(do_facet mds1 \
10802                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10803                awk '/ldlm_cancel/ {print $2}')
10804         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10805                awk '/ldlm_bl_callback/ {print $2}')
10806         chmod a+x $DIR/$tdir
10807         can2=$(do_facet mds1 \
10808                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10809                awk '/ldlm_cancel/ {print $2}')
10810         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10811                awk '/ldlm_bl_callback/ {print $2}')
10812         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10813         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10814         lru_resize_enable mdc
10815         lru_resize_enable osc
10816 }
10817 run_test 120d "Early Lock Cancel: setattr test"
10818
10819 test_120e() {
10820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10821         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10822                 skip_env "no early lock cancel on server"
10823         remote_mds_nodsh && skip "remote MDS with nodsh"
10824
10825         local dlmtrace_set=false
10826
10827         test_mkdir -i0 -c1 $DIR/$tdir
10828         lru_resize_disable mdc
10829         lru_resize_disable osc
10830         ! $LCTL get_param debug | grep -q dlmtrace &&
10831                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10832         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10833         cancel_lru_locks mdc
10834         cancel_lru_locks osc
10835         dd if=$DIR/$tdir/f1 of=/dev/null
10836         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10837         # XXX client can not do early lock cancel of OST lock
10838         # during unlink (LU-4206), so cancel osc lock now.
10839         sleep 2
10840         cancel_lru_locks osc
10841         can1=$(do_facet mds1 \
10842                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10843                awk '/ldlm_cancel/ {print $2}')
10844         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10845                awk '/ldlm_bl_callback/ {print $2}')
10846         unlink $DIR/$tdir/f1
10847         sleep 5
10848         can2=$(do_facet mds1 \
10849                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10850                awk '/ldlm_cancel/ {print $2}')
10851         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10852                awk '/ldlm_bl_callback/ {print $2}')
10853         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10854                 $LCTL dk $TMP/cancel.debug.txt
10855         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10856                 $LCTL dk $TMP/blocking.debug.txt
10857         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10858         lru_resize_enable mdc
10859         lru_resize_enable osc
10860 }
10861 run_test 120e "Early Lock Cancel: unlink test"
10862
10863 test_120f() {
10864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10865         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10866                 skip_env "no early lock cancel on server"
10867         remote_mds_nodsh && skip "remote MDS with nodsh"
10868
10869         test_mkdir -i0 -c1 $DIR/$tdir
10870         lru_resize_disable mdc
10871         lru_resize_disable osc
10872         test_mkdir -i0 -c1 $DIR/$tdir/d1
10873         test_mkdir -i0 -c1 $DIR/$tdir/d2
10874         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10875         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10876         cancel_lru_locks mdc
10877         cancel_lru_locks osc
10878         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10879         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10880         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10881         # XXX client can not do early lock cancel of OST lock
10882         # during rename (LU-4206), so cancel osc lock now.
10883         sleep 2
10884         cancel_lru_locks osc
10885         can1=$(do_facet mds1 \
10886                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10887                awk '/ldlm_cancel/ {print $2}')
10888         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10889                awk '/ldlm_bl_callback/ {print $2}')
10890         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10891         sleep 5
10892         can2=$(do_facet mds1 \
10893                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10894                awk '/ldlm_cancel/ {print $2}')
10895         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10896                awk '/ldlm_bl_callback/ {print $2}')
10897         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10898         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10899         lru_resize_enable mdc
10900         lru_resize_enable osc
10901 }
10902 run_test 120f "Early Lock Cancel: rename test"
10903
10904 test_120g() {
10905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10906         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10907                 skip_env "no early lock cancel on server"
10908         remote_mds_nodsh && skip "remote MDS with nodsh"
10909
10910         lru_resize_disable mdc
10911         lru_resize_disable osc
10912         count=10000
10913         echo create $count files
10914         test_mkdir $DIR/$tdir
10915         cancel_lru_locks mdc
10916         cancel_lru_locks osc
10917         t0=$(date +%s)
10918
10919         can0=$(do_facet $SINGLEMDS \
10920                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10921                awk '/ldlm_cancel/ {print $2}')
10922         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10923                awk '/ldlm_bl_callback/ {print $2}')
10924         createmany -o $DIR/$tdir/f $count
10925         sync
10926         can1=$(do_facet $SINGLEMDS \
10927                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10928                awk '/ldlm_cancel/ {print $2}')
10929         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10930                awk '/ldlm_bl_callback/ {print $2}')
10931         t1=$(date +%s)
10932         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10933         echo rm $count files
10934         rm -r $DIR/$tdir
10935         sync
10936         can2=$(do_facet $SINGLEMDS \
10937                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10938                awk '/ldlm_cancel/ {print $2}')
10939         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10940                awk '/ldlm_bl_callback/ {print $2}')
10941         t2=$(date +%s)
10942         echo total: $count removes in $((t2-t1))
10943         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10944         sleep 2
10945         # wait for commitment of removal
10946         lru_resize_enable mdc
10947         lru_resize_enable osc
10948 }
10949 run_test 120g "Early Lock Cancel: performance test"
10950
10951 test_121() { #bug #10589
10952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10953
10954         rm -rf $DIR/$tfile
10955         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10956 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10957         lctl set_param fail_loc=0x310
10958         cancel_lru_locks osc > /dev/null
10959         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10960         lctl set_param fail_loc=0
10961         [[ $reads -eq $writes ]] ||
10962                 error "read $reads blocks, must be $writes blocks"
10963 }
10964 run_test 121 "read cancel race ========="
10965
10966 test_123a() { # was test 123, statahead(bug 11401)
10967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10968
10969         SLOWOK=0
10970         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10971                 log "testing UP system. Performance may be lower than expected."
10972                 SLOWOK=1
10973         fi
10974
10975         rm -rf $DIR/$tdir
10976         test_mkdir $DIR/$tdir
10977         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10978         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10979         MULT=10
10980         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10981                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10982
10983                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10984                 lctl set_param -n llite.*.statahead_max 0
10985                 lctl get_param llite.*.statahead_max
10986                 cancel_lru_locks mdc
10987                 cancel_lru_locks osc
10988                 stime=`date +%s`
10989                 time ls -l $DIR/$tdir | wc -l
10990                 etime=`date +%s`
10991                 delta=$((etime - stime))
10992                 log "ls $i files without statahead: $delta sec"
10993                 lctl set_param llite.*.statahead_max=$max
10994
10995                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10996                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10997                 cancel_lru_locks mdc
10998                 cancel_lru_locks osc
10999                 stime=`date +%s`
11000                 time ls -l $DIR/$tdir | wc -l
11001                 etime=`date +%s`
11002                 delta_sa=$((etime - stime))
11003                 log "ls $i files with statahead: $delta_sa sec"
11004                 lctl get_param -n llite.*.statahead_stats
11005                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11006
11007                 [[ $swrong -lt $ewrong ]] &&
11008                         log "statahead was stopped, maybe too many locks held!"
11009                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11010
11011                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11012                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11013                     lctl set_param -n llite.*.statahead_max 0
11014                     lctl get_param llite.*.statahead_max
11015                     cancel_lru_locks mdc
11016                     cancel_lru_locks osc
11017                     stime=`date +%s`
11018                     time ls -l $DIR/$tdir | wc -l
11019                     etime=`date +%s`
11020                     delta=$((etime - stime))
11021                     log "ls $i files again without statahead: $delta sec"
11022                     lctl set_param llite.*.statahead_max=$max
11023                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11024                         if [  $SLOWOK -eq 0 ]; then
11025                                 error "ls $i files is slower with statahead!"
11026                         else
11027                                 log "ls $i files is slower with statahead!"
11028                         fi
11029                         break
11030                     fi
11031                 fi
11032
11033                 [ $delta -gt 20 ] && break
11034                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11035                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11036         done
11037         log "ls done"
11038
11039         stime=`date +%s`
11040         rm -r $DIR/$tdir
11041         sync
11042         etime=`date +%s`
11043         delta=$((etime - stime))
11044         log "rm -r $DIR/$tdir/: $delta seconds"
11045         log "rm done"
11046         lctl get_param -n llite.*.statahead_stats
11047 }
11048 run_test 123a "verify statahead work"
11049
11050 test_123b () { # statahead(bug 15027)
11051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11052
11053         test_mkdir $DIR/$tdir
11054         createmany -o $DIR/$tdir/$tfile-%d 1000
11055
11056         cancel_lru_locks mdc
11057         cancel_lru_locks osc
11058
11059 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11060         lctl set_param fail_loc=0x80000803
11061         ls -lR $DIR/$tdir > /dev/null
11062         log "ls done"
11063         lctl set_param fail_loc=0x0
11064         lctl get_param -n llite.*.statahead_stats
11065         rm -r $DIR/$tdir
11066         sync
11067
11068 }
11069 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11070
11071 test_124a() {
11072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11073         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11074                 skip_env "no lru resize on server"
11075
11076         local NR=2000
11077
11078         test_mkdir $DIR/$tdir
11079
11080         log "create $NR files at $DIR/$tdir"
11081         createmany -o $DIR/$tdir/f $NR ||
11082                 error "failed to create $NR files in $DIR/$tdir"
11083
11084         cancel_lru_locks mdc
11085         ls -l $DIR/$tdir > /dev/null
11086
11087         local NSDIR=""
11088         local LRU_SIZE=0
11089         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11090                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11091                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11092                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11093                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11094                         log "NSDIR=$NSDIR"
11095                         log "NS=$(basename $NSDIR)"
11096                         break
11097                 fi
11098         done
11099
11100         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11101                 skip "Not enough cached locks created!"
11102         fi
11103         log "LRU=$LRU_SIZE"
11104
11105         local SLEEP=30
11106
11107         # We know that lru resize allows one client to hold $LIMIT locks
11108         # for 10h. After that locks begin to be killed by client.
11109         local MAX_HRS=10
11110         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11111         log "LIMIT=$LIMIT"
11112         if [ $LIMIT -lt $LRU_SIZE ]; then
11113                 skip "Limit is too small $LIMIT"
11114         fi
11115
11116         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11117         # killing locks. Some time was spent for creating locks. This means
11118         # that up to the moment of sleep finish we must have killed some of
11119         # them (10-100 locks). This depends on how fast ther were created.
11120         # Many of them were touched in almost the same moment and thus will
11121         # be killed in groups.
11122         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11123
11124         # Use $LRU_SIZE_B here to take into account real number of locks
11125         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11126         local LRU_SIZE_B=$LRU_SIZE
11127         log "LVF=$LVF"
11128         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11129         log "OLD_LVF=$OLD_LVF"
11130         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11131
11132         # Let's make sure that we really have some margin. Client checks
11133         # cached locks every 10 sec.
11134         SLEEP=$((SLEEP+20))
11135         log "Sleep ${SLEEP} sec"
11136         local SEC=0
11137         while ((SEC<$SLEEP)); do
11138                 echo -n "..."
11139                 sleep 5
11140                 SEC=$((SEC+5))
11141                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11142                 echo -n "$LRU_SIZE"
11143         done
11144         echo ""
11145         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11146         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11147
11148         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11149                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11150                 unlinkmany $DIR/$tdir/f $NR
11151                 return
11152         }
11153
11154         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11155         log "unlink $NR files at $DIR/$tdir"
11156         unlinkmany $DIR/$tdir/f $NR
11157 }
11158 run_test 124a "lru resize ======================================="
11159
11160 get_max_pool_limit()
11161 {
11162         local limit=$($LCTL get_param \
11163                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11164         local max=0
11165         for l in $limit; do
11166                 if [[ $l -gt $max ]]; then
11167                         max=$l
11168                 fi
11169         done
11170         echo $max
11171 }
11172
11173 test_124b() {
11174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11175         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11176                 skip_env "no lru resize on server"
11177
11178         LIMIT=$(get_max_pool_limit)
11179
11180         NR=$(($(default_lru_size)*20))
11181         if [[ $NR -gt $LIMIT ]]; then
11182                 log "Limit lock number by $LIMIT locks"
11183                 NR=$LIMIT
11184         fi
11185
11186         IFree=$(mdsrate_inodes_available)
11187         if [ $IFree -lt $NR ]; then
11188                 log "Limit lock number by $IFree inodes"
11189                 NR=$IFree
11190         fi
11191
11192         lru_resize_disable mdc
11193         test_mkdir -p $DIR/$tdir/disable_lru_resize
11194
11195         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11196         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11197         cancel_lru_locks mdc
11198         stime=`date +%s`
11199         PID=""
11200         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11201         PID="$PID $!"
11202         sleep 2
11203         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11204         PID="$PID $!"
11205         sleep 2
11206         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11207         PID="$PID $!"
11208         wait $PID
11209         etime=`date +%s`
11210         nolruresize_delta=$((etime-stime))
11211         log "ls -la time: $nolruresize_delta seconds"
11212         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11213         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11214
11215         lru_resize_enable mdc
11216         test_mkdir -p $DIR/$tdir/enable_lru_resize
11217
11218         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11219         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11220         cancel_lru_locks mdc
11221         stime=`date +%s`
11222         PID=""
11223         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11224         PID="$PID $!"
11225         sleep 2
11226         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11227         PID="$PID $!"
11228         sleep 2
11229         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11230         PID="$PID $!"
11231         wait $PID
11232         etime=`date +%s`
11233         lruresize_delta=$((etime-stime))
11234         log "ls -la time: $lruresize_delta seconds"
11235         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11236
11237         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11238                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11239         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11240                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11241         else
11242                 log "lru resize performs the same with no lru resize"
11243         fi
11244         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11245 }
11246 run_test 124b "lru resize (performance test) ======================="
11247
11248 test_124c() {
11249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11250         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11251                 skip_env "no lru resize on server"
11252
11253         # cache ununsed locks on client
11254         local nr=100
11255         cancel_lru_locks mdc
11256         test_mkdir $DIR/$tdir
11257         createmany -o $DIR/$tdir/f $nr ||
11258                 error "failed to create $nr files in $DIR/$tdir"
11259         ls -l $DIR/$tdir > /dev/null
11260
11261         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11262         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11263         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11264         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11265         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11266
11267         # set lru_max_age to 1 sec
11268         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11269         echo "sleep $((recalc_p * 2)) seconds..."
11270         sleep $((recalc_p * 2))
11271
11272         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11273         # restore lru_max_age
11274         $LCTL set_param -n $nsdir.lru_max_age $max_age
11275         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11276         unlinkmany $DIR/$tdir/f $nr
11277 }
11278 run_test 124c "LRUR cancel very aged locks"
11279
11280 test_124d() {
11281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11282         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11283                 skip_env "no lru resize on server"
11284
11285         # cache ununsed locks on client
11286         local nr=100
11287
11288         lru_resize_disable mdc
11289         stack_trap "lru_resize_enable mdc" EXIT
11290
11291         cancel_lru_locks mdc
11292
11293         # asynchronous object destroy at MDT could cause bl ast to client
11294         test_mkdir $DIR/$tdir
11295         createmany -o $DIR/$tdir/f $nr ||
11296                 error "failed to create $nr files in $DIR/$tdir"
11297         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11298
11299         ls -l $DIR/$tdir > /dev/null
11300
11301         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11302         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11303         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11304         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11305
11306         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11307
11308         # set lru_max_age to 1 sec
11309         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11310         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11311
11312         echo "sleep $((recalc_p * 2)) seconds..."
11313         sleep $((recalc_p * 2))
11314
11315         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11316
11317         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11318 }
11319 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11320
11321 test_125() { # 13358
11322         $LCTL get_param -n llite.*.client_type | grep -q local ||
11323                 skip "must run as local client"
11324         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11325                 skip_env "must have acl enabled"
11326         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11327
11328         test_mkdir $DIR/$tdir
11329         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11330         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
11331         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
11332 }
11333 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
11334
11335 test_126() { # bug 12829/13455
11336         $GSS && skip_env "must run as gss disabled"
11337         $LCTL get_param -n llite.*.client_type | grep -q local ||
11338                 skip "must run as local client"
11339         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
11340
11341         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
11342         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
11343         rm -f $DIR/$tfile
11344         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
11345 }
11346 run_test 126 "check that the fsgid provided by the client is taken into account"
11347
11348 test_127a() { # bug 15521
11349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11350
11351         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
11352         $LCTL set_param osc.*.stats=0
11353         FSIZE=$((2048 * 1024))
11354         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
11355         cancel_lru_locks osc
11356         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
11357
11358         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
11359         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
11360                 echo "got $COUNT $NAME"
11361                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
11362                 eval $NAME=$COUNT || error "Wrong proc format"
11363
11364                 case $NAME in
11365                         read_bytes|write_bytes)
11366                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
11367                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
11368                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
11369                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
11370                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
11371                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
11372                                 error "sumsquare is too small: $SUMSQ"
11373                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
11374                                 error "sumsquare is too big: $SUMSQ"
11375                         ;;
11376                         *) ;;
11377                 esac
11378         done < $DIR/${tfile}.tmp
11379
11380         #check that we actually got some stats
11381         [ "$read_bytes" ] || error "Missing read_bytes stats"
11382         [ "$write_bytes" ] || error "Missing write_bytes stats"
11383         [ "$read_bytes" != 0 ] || error "no read done"
11384         [ "$write_bytes" != 0 ] || error "no write done"
11385 }
11386 run_test 127a "verify the client stats are sane"
11387
11388 test_127b() { # bug LU-333
11389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11390         local name count samp unit min max sum sumsq
11391
11392         $LCTL set_param llite.*.stats=0
11393
11394         # perform 2 reads and writes so MAX is different from SUM.
11395         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11396         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11397         cancel_lru_locks osc
11398         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11399         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11400
11401         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
11402         while read name count samp unit min max sum sumsq; do
11403                 echo "got $count $name"
11404                 eval $name=$count || error "Wrong proc format"
11405
11406                 case $name in
11407                 read_bytes)
11408                         [ $count -ne 2 ] && error "count is not 2: $count"
11409                         [ $min -ne $PAGE_SIZE ] &&
11410                                 error "min is not $PAGE_SIZE: $min"
11411                         [ $max -ne $PAGE_SIZE ] &&
11412                                 error "max is incorrect: $max"
11413                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
11414                                 error "sum is wrong: $sum"
11415                         ;;
11416                 write_bytes)
11417                         [ $count -ne 2 ] && error "count is not 2: $count"
11418                         [ $min -ne $PAGE_SIZE ] &&
11419                                 error "min is not $PAGE_SIZE: $min"
11420                         [ $max -ne $PAGE_SIZE ] &&
11421                                 error "max is incorrect: $max"
11422                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
11423                                 error "sum is wrong: $sum"
11424                         ;;
11425                 *) ;;
11426                 esac
11427         done < $TMP/$tfile.tmp
11428
11429         #check that we actually got some stats
11430         [ "$read_bytes" ] || error "Missing read_bytes stats"
11431         [ "$write_bytes" ] || error "Missing write_bytes stats"
11432         [ "$read_bytes" != 0 ] || error "no read done"
11433         [ "$write_bytes" != 0 ] || error "no write done"
11434
11435         rm -f $TMP/${tfile}.tmp
11436 }
11437 run_test 127b "verify the llite client stats are sane"
11438
11439 test_127c() { # LU-12394
11440         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11441         local size
11442         local bsize
11443         local reads
11444         local writes
11445         local count
11446
11447         $LCTL set_param llite.*.extents_stats=1
11448         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
11449
11450         # Use two stripes so there is enough space in default config
11451         $LFS setstripe -c 2 $DIR/$tfile
11452
11453         # Extent stats start at 0-4K and go in power of two buckets
11454         # LL_HIST_START = 12 --> 2^12 = 4K
11455         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
11456         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
11457         # small configs
11458         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
11459                 do
11460                 # Write and read, 2x each, second time at a non-zero offset
11461                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
11462                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
11463                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
11464                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
11465                 rm -f $DIR/$tfile
11466         done
11467
11468         $LCTL get_param llite.*.extents_stats
11469
11470         count=2
11471         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
11472                 do
11473                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
11474                                 grep -m 1 $bsize)
11475                 reads=$(echo $bucket | awk '{print $5}')
11476                 writes=$(echo $bucket | awk '{print $9}')
11477                 [ "$reads" -eq $count ] ||
11478                         error "$reads reads in < $bsize bucket, expect $count"
11479                 [ "$writes" -eq $count ] ||
11480                         error "$writes writes in < $bsize bucket, expect $count"
11481         done
11482
11483         # Test mmap write and read
11484         $LCTL set_param llite.*.extents_stats=c
11485         size=512
11486         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
11487         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
11488         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
11489
11490         $LCTL get_param llite.*.extents_stats
11491
11492         count=$(((size*1024) / PAGE_SIZE))
11493
11494         bsize=$((2 * PAGE_SIZE / 1024))K
11495
11496         bucket=$($LCTL get_param -n llite.*.extents_stats |
11497                         grep -m 1 $bsize)
11498         reads=$(echo $bucket | awk '{print $5}')
11499         writes=$(echo $bucket | awk '{print $9}')
11500         # mmap writes fault in the page first, creating an additonal read
11501         [ "$reads" -eq $((2 * count)) ] ||
11502                 error "$reads reads in < $bsize bucket, expect $count"
11503         [ "$writes" -eq $count ] ||
11504                 error "$writes writes in < $bsize bucket, expect $count"
11505 }
11506 run_test 127c "test llite extent stats with regular & mmap i/o"
11507
11508 test_128() { # bug 15212
11509         touch $DIR/$tfile
11510         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11511                 find $DIR/$tfile
11512                 find $DIR/$tfile
11513         EOF
11514
11515         result=$(grep error $TMP/$tfile.log)
11516         rm -f $DIR/$tfile $TMP/$tfile.log
11517         [ -z "$result" ] ||
11518                 error "consecutive find's under interactive lfs failed"
11519 }
11520 run_test 128 "interactive lfs for 2 consecutive find's"
11521
11522 set_dir_limits () {
11523         local mntdev
11524         local canondev
11525         local node
11526
11527         local ldproc=/proc/fs/ldiskfs
11528         local facets=$(get_facets MDS)
11529
11530         for facet in ${facets//,/ }; do
11531                 canondev=$(ldiskfs_canon \
11532                            *.$(convert_facet2label $facet).mntdev $facet)
11533                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11534                         ldproc=/sys/fs/ldiskfs
11535                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11536                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11537         done
11538 }
11539
11540 check_mds_dmesg() {
11541         local facets=$(get_facets MDS)
11542         for facet in ${facets//,/ }; do
11543                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11544         done
11545         return 1
11546 }
11547
11548 test_129() {
11549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11550         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11551                 skip "Need MDS version with at least 2.5.56"
11552         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11553                 skip_env "ldiskfs only test"
11554         fi
11555         remote_mds_nodsh && skip "remote MDS with nodsh"
11556
11557         local ENOSPC=28
11558         local EFBIG=27
11559         local has_warning=false
11560
11561         rm -rf $DIR/$tdir
11562         mkdir -p $DIR/$tdir
11563
11564         # block size of mds1
11565         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11566         set_dir_limits $maxsize $maxsize
11567         local dirsize=$(stat -c%s "$DIR/$tdir")
11568         local nfiles=0
11569         while [[ $dirsize -le $maxsize ]]; do
11570                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11571                 rc=$?
11572                 if ! $has_warning; then
11573                         check_mds_dmesg '"is approaching"' && has_warning=true
11574                 fi
11575                 # check two errors:
11576                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11577                 # EFBIG for previous versions included in ldiskfs series
11578                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11579                         set_dir_limits 0 0
11580                         echo "return code $rc received as expected"
11581
11582                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11583                                 error_exit "create failed w/o dir size limit"
11584
11585                         check_mds_dmesg '"has reached"' ||
11586                                 error_exit "reached message should be output"
11587
11588                         [ $has_warning = "false" ] &&
11589                                 error_exit "warning message should be output"
11590
11591                         dirsize=$(stat -c%s "$DIR/$tdir")
11592
11593                         [[ $dirsize -ge $maxsize ]] && return 0
11594                         error_exit "current dir size $dirsize, " \
11595                                    "previous limit $maxsize"
11596                 elif [ $rc -ne 0 ]; then
11597                         set_dir_limits 0 0
11598                         error_exit "return $rc received instead of expected " \
11599                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11600                 fi
11601                 nfiles=$((nfiles + 1))
11602                 dirsize=$(stat -c%s "$DIR/$tdir")
11603         done
11604
11605         set_dir_limits 0 0
11606         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11607 }
11608 run_test 129 "test directory size limit ========================"
11609
11610 OLDIFS="$IFS"
11611 cleanup_130() {
11612         trap 0
11613         IFS="$OLDIFS"
11614 }
11615
11616 test_130a() {
11617         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11618         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11619
11620         trap cleanup_130 EXIT RETURN
11621
11622         local fm_file=$DIR/$tfile
11623         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11624         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11625                 error "dd failed for $fm_file"
11626
11627         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11628         filefrag -ves $fm_file
11629         RC=$?
11630         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11631                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11632         [ $RC != 0 ] && error "filefrag $fm_file failed"
11633
11634         filefrag_op=$(filefrag -ve -k $fm_file |
11635                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11636         lun=$($LFS getstripe -i $fm_file)
11637
11638         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11639         IFS=$'\n'
11640         tot_len=0
11641         for line in $filefrag_op
11642         do
11643                 frag_lun=`echo $line | cut -d: -f5`
11644                 ext_len=`echo $line | cut -d: -f4`
11645                 if (( $frag_lun != $lun )); then
11646                         cleanup_130
11647                         error "FIEMAP on 1-stripe file($fm_file) failed"
11648                         return
11649                 fi
11650                 (( tot_len += ext_len ))
11651         done
11652
11653         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11654                 cleanup_130
11655                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11656                 return
11657         fi
11658
11659         cleanup_130
11660
11661         echo "FIEMAP on single striped file succeeded"
11662 }
11663 run_test 130a "FIEMAP (1-stripe file)"
11664
11665 test_130b() {
11666         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11667
11668         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11669         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11670
11671         trap cleanup_130 EXIT RETURN
11672
11673         local fm_file=$DIR/$tfile
11674         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11675                         error "setstripe on $fm_file"
11676         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11677                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11678
11679         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11680                 error "dd failed on $fm_file"
11681
11682         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11683         filefrag_op=$(filefrag -ve -k $fm_file |
11684                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11685
11686         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11687                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11688
11689         IFS=$'\n'
11690         tot_len=0
11691         num_luns=1
11692         for line in $filefrag_op
11693         do
11694                 frag_lun=$(echo $line | cut -d: -f5 |
11695                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11696                 ext_len=$(echo $line | cut -d: -f4)
11697                 if (( $frag_lun != $last_lun )); then
11698                         if (( tot_len != 1024 )); then
11699                                 cleanup_130
11700                                 error "FIEMAP on $fm_file failed; returned " \
11701                                 "len $tot_len for OST $last_lun instead of 1024"
11702                                 return
11703                         else
11704                                 (( num_luns += 1 ))
11705                                 tot_len=0
11706                         fi
11707                 fi
11708                 (( tot_len += ext_len ))
11709                 last_lun=$frag_lun
11710         done
11711         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11712                 cleanup_130
11713                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11714                         "luns or wrong len for OST $last_lun"
11715                 return
11716         fi
11717
11718         cleanup_130
11719
11720         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11721 }
11722 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11723
11724 test_130c() {
11725         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11726
11727         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11728         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11729
11730         trap cleanup_130 EXIT RETURN
11731
11732         local fm_file=$DIR/$tfile
11733         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11734         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11735                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11736
11737         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11738                         error "dd failed on $fm_file"
11739
11740         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11741         filefrag_op=$(filefrag -ve -k $fm_file |
11742                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11743
11744         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11745                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11746
11747         IFS=$'\n'
11748         tot_len=0
11749         num_luns=1
11750         for line in $filefrag_op
11751         do
11752                 frag_lun=$(echo $line | cut -d: -f5 |
11753                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11754                 ext_len=$(echo $line | cut -d: -f4)
11755                 if (( $frag_lun != $last_lun )); then
11756                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11757                         if (( logical != 512 )); then
11758                                 cleanup_130
11759                                 error "FIEMAP on $fm_file failed; returned " \
11760                                 "logical start for lun $logical instead of 512"
11761                                 return
11762                         fi
11763                         if (( tot_len != 512 )); then
11764                                 cleanup_130
11765                                 error "FIEMAP on $fm_file failed; returned " \
11766                                 "len $tot_len for OST $last_lun instead of 1024"
11767                                 return
11768                         else
11769                                 (( num_luns += 1 ))
11770                                 tot_len=0
11771                         fi
11772                 fi
11773                 (( tot_len += ext_len ))
11774                 last_lun=$frag_lun
11775         done
11776         if (( num_luns != 2 || tot_len != 512 )); then
11777                 cleanup_130
11778                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11779                         "luns or wrong len for OST $last_lun"
11780                 return
11781         fi
11782
11783         cleanup_130
11784
11785         echo "FIEMAP on 2-stripe file with hole succeeded"
11786 }
11787 run_test 130c "FIEMAP (2-stripe file with hole)"
11788
11789 test_130d() {
11790         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11791
11792         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11793         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11794
11795         trap cleanup_130 EXIT RETURN
11796
11797         local fm_file=$DIR/$tfile
11798         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11799                         error "setstripe on $fm_file"
11800         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11801                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11802
11803         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11804         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11805                 error "dd failed on $fm_file"
11806
11807         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11808         filefrag_op=$(filefrag -ve -k $fm_file |
11809                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11810
11811         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11812                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11813
11814         IFS=$'\n'
11815         tot_len=0
11816         num_luns=1
11817         for line in $filefrag_op
11818         do
11819                 frag_lun=$(echo $line | cut -d: -f5 |
11820                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11821                 ext_len=$(echo $line | cut -d: -f4)
11822                 if (( $frag_lun != $last_lun )); then
11823                         if (( tot_len != 1024 )); then
11824                                 cleanup_130
11825                                 error "FIEMAP on $fm_file failed; returned " \
11826                                 "len $tot_len for OST $last_lun instead of 1024"
11827                                 return
11828                         else
11829                                 (( num_luns += 1 ))
11830                                 tot_len=0
11831                         fi
11832                 fi
11833                 (( tot_len += ext_len ))
11834                 last_lun=$frag_lun
11835         done
11836         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11837                 cleanup_130
11838                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11839                         "luns or wrong len for OST $last_lun"
11840                 return
11841         fi
11842
11843         cleanup_130
11844
11845         echo "FIEMAP on N-stripe file succeeded"
11846 }
11847 run_test 130d "FIEMAP (N-stripe file)"
11848
11849 test_130e() {
11850         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11851
11852         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11853         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11854
11855         trap cleanup_130 EXIT RETURN
11856
11857         local fm_file=$DIR/$tfile
11858         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11859         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11860                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11861
11862         NUM_BLKS=512
11863         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11864         for ((i = 0; i < $NUM_BLKS; i++))
11865         do
11866                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11867         done
11868
11869         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11870         filefrag_op=$(filefrag -ve -k $fm_file |
11871                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11872
11873         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11874                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11875
11876         IFS=$'\n'
11877         tot_len=0
11878         num_luns=1
11879         for line in $filefrag_op
11880         do
11881                 frag_lun=$(echo $line | cut -d: -f5 |
11882                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11883                 ext_len=$(echo $line | cut -d: -f4)
11884                 if (( $frag_lun != $last_lun )); then
11885                         if (( tot_len != $EXPECTED_LEN )); then
11886                                 cleanup_130
11887                                 error "FIEMAP on $fm_file failed; returned " \
11888                                 "len $tot_len for OST $last_lun instead " \
11889                                 "of $EXPECTED_LEN"
11890                                 return
11891                         else
11892                                 (( num_luns += 1 ))
11893                                 tot_len=0
11894                         fi
11895                 fi
11896                 (( tot_len += ext_len ))
11897                 last_lun=$frag_lun
11898         done
11899         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11900                 cleanup_130
11901                 error "FIEMAP on $fm_file failed; returned wrong number " \
11902                         "of luns or wrong len for OST $last_lun"
11903                 return
11904         fi
11905
11906         cleanup_130
11907
11908         echo "FIEMAP with continuation calls succeeded"
11909 }
11910 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11911
11912 test_130f() {
11913         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11914         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11915
11916         local fm_file=$DIR/$tfile
11917         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
11918                 error "multiop create with lov_delay_create on $fm_file"
11919
11920         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11921         filefrag_extents=$(filefrag -vek $fm_file |
11922                            awk '/extents? found/ { print $2 }')
11923         if [[ "$filefrag_extents" != "0" ]]; then
11924                 error "FIEMAP on $fm_file failed; " \
11925                       "returned $filefrag_extents expected 0"
11926         fi
11927
11928         rm -f $fm_file
11929 }
11930 run_test 130f "FIEMAP (unstriped file)"
11931
11932 # Test for writev/readv
11933 test_131a() {
11934         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
11935                 error "writev test failed"
11936         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
11937                 error "readv failed"
11938         rm -f $DIR/$tfile
11939 }
11940 run_test 131a "test iov's crossing stripe boundary for writev/readv"
11941
11942 test_131b() {
11943         local fsize=$((524288 + 1048576 + 1572864))
11944         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
11945                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11946                         error "append writev test failed"
11947
11948         ((fsize += 1572864 + 1048576))
11949         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
11950                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11951                         error "append writev test failed"
11952         rm -f $DIR/$tfile
11953 }
11954 run_test 131b "test append writev"
11955
11956 test_131c() {
11957         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
11958         error "NOT PASS"
11959 }
11960 run_test 131c "test read/write on file w/o objects"
11961
11962 test_131d() {
11963         rwv -f $DIR/$tfile -w -n 1 1572864
11964         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
11965         if [ "$NOB" != 1572864 ]; then
11966                 error "Short read filed: read $NOB bytes instead of 1572864"
11967         fi
11968         rm -f $DIR/$tfile
11969 }
11970 run_test 131d "test short read"
11971
11972 test_131e() {
11973         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
11974         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
11975         error "read hitting hole failed"
11976         rm -f $DIR/$tfile
11977 }
11978 run_test 131e "test read hitting hole"
11979
11980 check_stats() {
11981         local facet=$1
11982         local op=$2
11983         local want=${3:-0}
11984         local res
11985
11986         case $facet in
11987         mds*) res=$(do_facet $facet \
11988                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
11989                  ;;
11990         ost*) res=$(do_facet $facet \
11991                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
11992                  ;;
11993         *) error "Wrong facet '$facet'" ;;
11994         esac
11995         [ "$res" ] || error "The counter for $op on $facet was not incremented"
11996         # if the argument $3 is zero, it means any stat increment is ok.
11997         if [[ $want -gt 0 ]]; then
11998                 local count=$(echo $res | awk '{ print $2 }')
11999                 [[ $count -ne $want ]] &&
12000                         error "The $op counter on $facet is $count, not $want"
12001         fi
12002 }
12003
12004 test_133a() {
12005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12006         remote_ost_nodsh && skip "remote OST with nodsh"
12007         remote_mds_nodsh && skip "remote MDS with nodsh"
12008         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12009                 skip_env "MDS doesn't support rename stats"
12010
12011         local testdir=$DIR/${tdir}/stats_testdir
12012
12013         mkdir -p $DIR/${tdir}
12014
12015         # clear stats.
12016         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12017         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12018
12019         # verify mdt stats first.
12020         mkdir ${testdir} || error "mkdir failed"
12021         check_stats $SINGLEMDS "mkdir" 1
12022         touch ${testdir}/${tfile} || error "touch failed"
12023         check_stats $SINGLEMDS "open" 1
12024         check_stats $SINGLEMDS "close" 1
12025         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12026                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12027                 check_stats $SINGLEMDS "mknod" 2
12028         }
12029         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12030         check_stats $SINGLEMDS "unlink" 1
12031         rm -f ${testdir}/${tfile} || error "file remove failed"
12032         check_stats $SINGLEMDS "unlink" 2
12033
12034         # remove working dir and check mdt stats again.
12035         rmdir ${testdir} || error "rmdir failed"
12036         check_stats $SINGLEMDS "rmdir" 1
12037
12038         local testdir1=$DIR/${tdir}/stats_testdir1
12039         mkdir -p ${testdir}
12040         mkdir -p ${testdir1}
12041         touch ${testdir1}/test1
12042         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12043         check_stats $SINGLEMDS "crossdir_rename" 1
12044
12045         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12046         check_stats $SINGLEMDS "samedir_rename" 1
12047
12048         rm -rf $DIR/${tdir}
12049 }
12050 run_test 133a "Verifying MDT stats ========================================"
12051
12052 test_133b() {
12053         local res
12054
12055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12056         remote_ost_nodsh && skip "remote OST with nodsh"
12057         remote_mds_nodsh && skip "remote MDS with nodsh"
12058
12059         local testdir=$DIR/${tdir}/stats_testdir
12060
12061         mkdir -p ${testdir} || error "mkdir failed"
12062         touch ${testdir}/${tfile} || error "touch failed"
12063         cancel_lru_locks mdc
12064
12065         # clear stats.
12066         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12067         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12068
12069         # extra mdt stats verification.
12070         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12071         check_stats $SINGLEMDS "setattr" 1
12072         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12073         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12074         then            # LU-1740
12075                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12076                 check_stats $SINGLEMDS "getattr" 1
12077         fi
12078         rm -rf $DIR/${tdir}
12079
12080         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12081         # so the check below is not reliable
12082         [ $MDSCOUNT -eq 1 ] || return 0
12083
12084         # Sleep to avoid a cached response.
12085         #define OBD_STATFS_CACHE_SECONDS 1
12086         sleep 2
12087         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12088         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12089         $LFS df || error "lfs failed"
12090         check_stats $SINGLEMDS "statfs" 1
12091
12092         # check aggregated statfs (LU-10018)
12093         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12094                 return 0
12095         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12096                 return 0
12097         sleep 2
12098         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12099         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12100         df $DIR
12101         check_stats $SINGLEMDS "statfs" 1
12102
12103         # We want to check that the client didn't send OST_STATFS to
12104         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12105         # extra care is needed here.
12106         if remote_mds; then
12107                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12108                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12109
12110                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12111                 [ "$res" ] && error "OST got STATFS"
12112         fi
12113
12114         return 0
12115 }
12116 run_test 133b "Verifying extra MDT stats =================================="
12117
12118 test_133c() {
12119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12120         remote_ost_nodsh && skip "remote OST with nodsh"
12121         remote_mds_nodsh && skip "remote MDS with nodsh"
12122
12123         local testdir=$DIR/$tdir/stats_testdir
12124
12125         test_mkdir -p $testdir
12126
12127         # verify obdfilter stats.
12128         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12129         sync
12130         cancel_lru_locks osc
12131         wait_delete_completed
12132
12133         # clear stats.
12134         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12135         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12136
12137         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12138                 error "dd failed"
12139         sync
12140         cancel_lru_locks osc
12141         check_stats ost1 "write" 1
12142
12143         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12144         check_stats ost1 "read" 1
12145
12146         > $testdir/$tfile || error "truncate failed"
12147         check_stats ost1 "punch" 1
12148
12149         rm -f $testdir/$tfile || error "file remove failed"
12150         wait_delete_completed
12151         check_stats ost1 "destroy" 1
12152
12153         rm -rf $DIR/$tdir
12154 }
12155 run_test 133c "Verifying OST stats ========================================"
12156
12157 order_2() {
12158         local value=$1
12159         local orig=$value
12160         local order=1
12161
12162         while [ $value -ge 2 ]; do
12163                 order=$((order*2))
12164                 value=$((value/2))
12165         done
12166
12167         if [ $orig -gt $order ]; then
12168                 order=$((order*2))
12169         fi
12170         echo $order
12171 }
12172
12173 size_in_KMGT() {
12174     local value=$1
12175     local size=('K' 'M' 'G' 'T');
12176     local i=0
12177     local size_string=$value
12178
12179     while [ $value -ge 1024 ]; do
12180         if [ $i -gt 3 ]; then
12181             #T is the biggest unit we get here, if that is bigger,
12182             #just return XXXT
12183             size_string=${value}T
12184             break
12185         fi
12186         value=$((value >> 10))
12187         if [ $value -lt 1024 ]; then
12188             size_string=${value}${size[$i]}
12189             break
12190         fi
12191         i=$((i + 1))
12192     done
12193
12194     echo $size_string
12195 }
12196
12197 get_rename_size() {
12198         local size=$1
12199         local context=${2:-.}
12200         local sample=$(do_facet $SINGLEMDS $LCTL \
12201                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12202                 grep -A1 $context |
12203                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12204         echo $sample
12205 }
12206
12207 test_133d() {
12208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12209         remote_ost_nodsh && skip "remote OST with nodsh"
12210         remote_mds_nodsh && skip "remote MDS with nodsh"
12211         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12212                 skip_env "MDS doesn't support rename stats"
12213
12214         local testdir1=$DIR/${tdir}/stats_testdir1
12215         local testdir2=$DIR/${tdir}/stats_testdir2
12216         mkdir -p $DIR/${tdir}
12217
12218         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12219
12220         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12221         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12222
12223         createmany -o $testdir1/test 512 || error "createmany failed"
12224
12225         # check samedir rename size
12226         mv ${testdir1}/test0 ${testdir1}/test_0
12227
12228         local testdir1_size=$(ls -l $DIR/${tdir} |
12229                 awk '/stats_testdir1/ {print $5}')
12230         local testdir2_size=$(ls -l $DIR/${tdir} |
12231                 awk '/stats_testdir2/ {print $5}')
12232
12233         testdir1_size=$(order_2 $testdir1_size)
12234         testdir2_size=$(order_2 $testdir2_size)
12235
12236         testdir1_size=$(size_in_KMGT $testdir1_size)
12237         testdir2_size=$(size_in_KMGT $testdir2_size)
12238
12239         echo "source rename dir size: ${testdir1_size}"
12240         echo "target rename dir size: ${testdir2_size}"
12241
12242         local cmd="do_facet $SINGLEMDS $LCTL "
12243         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12244
12245         eval $cmd || error "$cmd failed"
12246         local samedir=$($cmd | grep 'same_dir')
12247         local same_sample=$(get_rename_size $testdir1_size)
12248         [ -z "$samedir" ] && error "samedir_rename_size count error"
12249         [[ $same_sample -eq 1 ]] ||
12250                 error "samedir_rename_size error $same_sample"
12251         echo "Check same dir rename stats success"
12252
12253         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12254
12255         # check crossdir rename size
12256         mv ${testdir1}/test_0 ${testdir2}/test_0
12257
12258         testdir1_size=$(ls -l $DIR/${tdir} |
12259                 awk '/stats_testdir1/ {print $5}')
12260         testdir2_size=$(ls -l $DIR/${tdir} |
12261                 awk '/stats_testdir2/ {print $5}')
12262
12263         testdir1_size=$(order_2 $testdir1_size)
12264         testdir2_size=$(order_2 $testdir2_size)
12265
12266         testdir1_size=$(size_in_KMGT $testdir1_size)
12267         testdir2_size=$(size_in_KMGT $testdir2_size)
12268
12269         echo "source rename dir size: ${testdir1_size}"
12270         echo "target rename dir size: ${testdir2_size}"
12271
12272         eval $cmd || error "$cmd failed"
12273         local crossdir=$($cmd | grep 'crossdir')
12274         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12275         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12276         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12277         [[ $src_sample -eq 1 ]] ||
12278                 error "crossdir_rename_size error $src_sample"
12279         [[ $tgt_sample -eq 1 ]] ||
12280                 error "crossdir_rename_size error $tgt_sample"
12281         echo "Check cross dir rename stats success"
12282         rm -rf $DIR/${tdir}
12283 }
12284 run_test 133d "Verifying rename_stats ========================================"
12285
12286 test_133e() {
12287         remote_mds_nodsh && skip "remote MDS with nodsh"
12288         remote_ost_nodsh && skip "remote OST with nodsh"
12289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12290
12291         local testdir=$DIR/${tdir}/stats_testdir
12292         local ctr f0 f1 bs=32768 count=42 sum
12293
12294         mkdir -p ${testdir} || error "mkdir failed"
12295
12296         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12297
12298         for ctr in {write,read}_bytes; do
12299                 sync
12300                 cancel_lru_locks osc
12301
12302                 do_facet ost1 $LCTL set_param -n \
12303                         "obdfilter.*.exports.clear=clear"
12304
12305                 if [ $ctr = write_bytes ]; then
12306                         f0=/dev/zero
12307                         f1=${testdir}/${tfile}
12308                 else
12309                         f0=${testdir}/${tfile}
12310                         f1=/dev/null
12311                 fi
12312
12313                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12314                         error "dd failed"
12315                 sync
12316                 cancel_lru_locks osc
12317
12318                 sum=$(do_facet ost1 $LCTL get_param \
12319                         "obdfilter.*.exports.*.stats" |
12320                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12321                                 $1 == ctr { sum += $7 }
12322                                 END { printf("%0.0f", sum) }')
12323
12324                 if ((sum != bs * count)); then
12325                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12326                 fi
12327         done
12328
12329         rm -rf $DIR/${tdir}
12330 }
12331 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
12332
12333 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
12334
12335 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
12336 # not honor the -ignore_readdir_race option correctly. So we call
12337 # error_ignore() rather than error() in these cases. See LU-11152.
12338 error_133() {
12339         if (find --version; do_facet mds1 find --version) |
12340                 grep -q '\b4\.5\.1[1-4]\b'; then
12341                 error_ignore LU-11152 "$@"
12342         else
12343                 error "$@"
12344         fi
12345 }
12346
12347 test_133f() {
12348         # First without trusting modes.
12349         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
12350         echo "proc_dirs='$proc_dirs'"
12351         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
12352         find $proc_dirs -exec cat '{}' \; &> /dev/null
12353
12354         # Second verifying readability.
12355         $LCTL get_param -R '*' &> /dev/null
12356
12357         # Verifing writability with badarea_io.
12358         find $proc_dirs \
12359                 -ignore_readdir_race \
12360                 -type f \
12361                 -not -name force_lbug \
12362                 -not -name changelog_mask \
12363                 -exec badarea_io '{}' \; ||
12364                         error_133 "find $proc_dirs failed"
12365 }
12366 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
12367
12368 test_133g() {
12369         remote_mds_nodsh && skip "remote MDS with nodsh"
12370         remote_ost_nodsh && skip "remote OST with nodsh"
12371
12372         # eventually, this can also be replaced with "lctl get_param -R",
12373         # but not until that option is always available on the server
12374         local facet
12375         for facet in mds1 ost1; do
12376                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
12377                         skip_noexit "Too old lustre on $facet"
12378                 local facet_proc_dirs=$(do_facet $facet \
12379                                         \\\ls -d $proc_regexp 2>/dev/null)
12380                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12381                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12382                 do_facet $facet find $facet_proc_dirs \
12383                         ! -name req_history \
12384                         -exec cat '{}' \\\; &> /dev/null
12385
12386                 do_facet $facet find $facet_proc_dirs \
12387                         ! -name req_history \
12388                         -type f \
12389                         -exec cat '{}' \\\; &> /dev/null ||
12390                                 error "proc file read failed"
12391
12392                 do_facet $facet find $facet_proc_dirs \
12393                         -ignore_readdir_race \
12394                         -type f \
12395                         -not -name force_lbug \
12396                         -not -name changelog_mask \
12397                         -exec badarea_io '{}' \\\; ||
12398                                 error_133 "$facet find $facet_proc_dirs failed"
12399         done
12400
12401         # remount the FS in case writes/reads /proc break the FS
12402         cleanup || error "failed to unmount"
12403         setup || error "failed to setup"
12404         true
12405 }
12406 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
12407
12408 test_133h() {
12409         remote_mds_nodsh && skip "remote MDS with nodsh"
12410         remote_ost_nodsh && skip "remote OST with nodsh"
12411         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
12412                 skip "Need MDS version at least 2.9.54"
12413
12414         local facet
12415
12416         for facet in client mds1 ost1; do
12417                 local facet_proc_dirs=$(do_facet $facet \
12418                                         \\\ls -d $proc_regexp 2> /dev/null)
12419                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12420                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12421                 # Get the list of files that are missing the terminating newline
12422                 local missing=($(do_facet $facet \
12423                         find ${facet_proc_dirs} -type f \|              \
12424                                 while read F\; do                       \
12425                                         awk -v FS='\v' -v RS='\v\v'     \
12426                                         "'END { if(NR>0 &&              \
12427                                         \\\$NF !~ /.*\\\n\$/)           \
12428                                                 print FILENAME}'"       \
12429                                         '\$F'\;                         \
12430                                 done 2>/dev/null))
12431                 [ ${#missing[*]} -eq 0 ] ||
12432                         error "files do not end with newline: ${missing[*]}"
12433         done
12434 }
12435 run_test 133h "Proc files should end with newlines"
12436
12437 test_134a() {
12438         remote_mds_nodsh && skip "remote MDS with nodsh"
12439         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12440                 skip "Need MDS version at least 2.7.54"
12441
12442         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12443         cancel_lru_locks mdc
12444
12445         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12446         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12447         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12448
12449         local nr=1000
12450         createmany -o $DIR/$tdir/f $nr ||
12451                 error "failed to create $nr files in $DIR/$tdir"
12452         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12453
12454         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12455         do_facet mds1 $LCTL set_param fail_loc=0x327
12456         do_facet mds1 $LCTL set_param fail_val=500
12457         touch $DIR/$tdir/m
12458
12459         echo "sleep 10 seconds ..."
12460         sleep 10
12461         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12462
12463         do_facet mds1 $LCTL set_param fail_loc=0
12464         do_facet mds1 $LCTL set_param fail_val=0
12465         [ $lck_cnt -lt $unused ] ||
12466                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
12467
12468         rm $DIR/$tdir/m
12469         unlinkmany $DIR/$tdir/f $nr
12470 }
12471 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
12472
12473 test_134b() {
12474         remote_mds_nodsh && skip "remote MDS with nodsh"
12475         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12476                 skip "Need MDS version at least 2.7.54"
12477
12478         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12479         cancel_lru_locks mdc
12480
12481         local low_wm=$(do_facet mds1 $LCTL get_param -n \
12482                         ldlm.lock_reclaim_threshold_mb)
12483         # disable reclaim temporarily
12484         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
12485
12486         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12487         do_facet mds1 $LCTL set_param fail_loc=0x328
12488         do_facet mds1 $LCTL set_param fail_val=500
12489
12490         $LCTL set_param debug=+trace
12491
12492         local nr=600
12493         createmany -o $DIR/$tdir/f $nr &
12494         local create_pid=$!
12495
12496         echo "Sleep $TIMEOUT seconds ..."
12497         sleep $TIMEOUT
12498         if ! ps -p $create_pid  > /dev/null 2>&1; then
12499                 do_facet mds1 $LCTL set_param fail_loc=0
12500                 do_facet mds1 $LCTL set_param fail_val=0
12501                 do_facet mds1 $LCTL set_param \
12502                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12503                 error "createmany finished incorrectly!"
12504         fi
12505         do_facet mds1 $LCTL set_param fail_loc=0
12506         do_facet mds1 $LCTL set_param fail_val=0
12507         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12508         wait $create_pid || return 1
12509
12510         unlinkmany $DIR/$tdir/f $nr
12511 }
12512 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12513
12514 test_140() { #bug-17379
12515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12516
12517         test_mkdir $DIR/$tdir
12518         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12519         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12520
12521         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12522         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12523         local i=0
12524         while i=$((i + 1)); do
12525                 test_mkdir $i
12526                 cd $i || error "Changing to $i"
12527                 ln -s ../stat stat || error "Creating stat symlink"
12528                 # Read the symlink until ELOOP present,
12529                 # not LBUGing the system is considered success,
12530                 # we didn't overrun the stack.
12531                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12532                 if [ $ret -ne 0 ]; then
12533                         if [ $ret -eq 40 ]; then
12534                                 break  # -ELOOP
12535                         else
12536                                 error "Open stat symlink"
12537                                         return
12538                         fi
12539                 fi
12540         done
12541         i=$((i - 1))
12542         echo "The symlink depth = $i"
12543         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12544                 error "Invalid symlink depth"
12545
12546         # Test recursive symlink
12547         ln -s symlink_self symlink_self
12548         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12549         echo "open symlink_self returns $ret"
12550         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12551 }
12552 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12553
12554 test_150() {
12555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12556
12557         local TF="$TMP/$tfile"
12558
12559         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12560         cp $TF $DIR/$tfile
12561         cancel_lru_locks $OSC
12562         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12563         remount_client $MOUNT
12564         df -P $MOUNT
12565         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12566
12567         $TRUNCATE $TF 6000
12568         $TRUNCATE $DIR/$tfile 6000
12569         cancel_lru_locks $OSC
12570         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12571
12572         echo "12345" >>$TF
12573         echo "12345" >>$DIR/$tfile
12574         cancel_lru_locks $OSC
12575         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12576
12577         echo "12345" >>$TF
12578         echo "12345" >>$DIR/$tfile
12579         cancel_lru_locks $OSC
12580         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12581
12582         rm -f $TF
12583         true
12584 }
12585 run_test 150 "truncate/append tests"
12586
12587 #LU-2902 roc_hit was not able to read all values from lproc
12588 function roc_hit_init() {
12589         local list=$(comma_list $(osts_nodes))
12590         local dir=$DIR/$tdir-check
12591         local file=$dir/$tfile
12592         local BEFORE
12593         local AFTER
12594         local idx
12595
12596         test_mkdir $dir
12597         #use setstripe to do a write to every ost
12598         for i in $(seq 0 $((OSTCOUNT-1))); do
12599                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12600                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12601                 idx=$(printf %04x $i)
12602                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12603                         awk '$1 == "cache_access" {sum += $7}
12604                                 END { printf("%0.0f", sum) }')
12605
12606                 cancel_lru_locks osc
12607                 cat $file >/dev/null
12608
12609                 AFTER=$(get_osd_param $list *OST*$idx stats |
12610                         awk '$1 == "cache_access" {sum += $7}
12611                                 END { printf("%0.0f", sum) }')
12612
12613                 echo BEFORE:$BEFORE AFTER:$AFTER
12614                 if ! let "AFTER - BEFORE == 4"; then
12615                         rm -rf $dir
12616                         error "roc_hit is not safe to use"
12617                 fi
12618                 rm $file
12619         done
12620
12621         rm -rf $dir
12622 }
12623
12624 function roc_hit() {
12625         local list=$(comma_list $(osts_nodes))
12626         echo $(get_osd_param $list '' stats |
12627                 awk '$1 == "cache_hit" {sum += $7}
12628                         END { printf("%0.0f", sum) }')
12629 }
12630
12631 function set_cache() {
12632         local on=1
12633
12634         if [ "$2" == "off" ]; then
12635                 on=0;
12636         fi
12637         local list=$(comma_list $(osts_nodes))
12638         set_osd_param $list '' $1_cache_enable $on
12639
12640         cancel_lru_locks osc
12641 }
12642
12643 test_151() {
12644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12645         remote_ost_nodsh && skip "remote OST with nodsh"
12646
12647         local CPAGES=3
12648         local list=$(comma_list $(osts_nodes))
12649
12650         # check whether obdfilter is cache capable at all
12651         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12652                 skip "not cache-capable obdfilter"
12653         fi
12654
12655         # check cache is enabled on all obdfilters
12656         if get_osd_param $list '' read_cache_enable | grep 0; then
12657                 skip "oss cache is disabled"
12658         fi
12659
12660         set_osd_param $list '' writethrough_cache_enable 1
12661
12662         # check write cache is enabled on all obdfilters
12663         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12664                 skip "oss write cache is NOT enabled"
12665         fi
12666
12667         roc_hit_init
12668
12669         #define OBD_FAIL_OBD_NO_LRU  0x609
12670         do_nodes $list $LCTL set_param fail_loc=0x609
12671
12672         # pages should be in the case right after write
12673         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12674                 error "dd failed"
12675
12676         local BEFORE=$(roc_hit)
12677         cancel_lru_locks osc
12678         cat $DIR/$tfile >/dev/null
12679         local AFTER=$(roc_hit)
12680
12681         do_nodes $list $LCTL set_param fail_loc=0
12682
12683         if ! let "AFTER - BEFORE == CPAGES"; then
12684                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12685         fi
12686
12687         # the following read invalidates the cache
12688         cancel_lru_locks osc
12689         set_osd_param $list '' read_cache_enable 0
12690         cat $DIR/$tfile >/dev/null
12691
12692         # now data shouldn't be found in the cache
12693         BEFORE=$(roc_hit)
12694         cancel_lru_locks osc
12695         cat $DIR/$tfile >/dev/null
12696         AFTER=$(roc_hit)
12697         if let "AFTER - BEFORE != 0"; then
12698                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12699         fi
12700
12701         set_osd_param $list '' read_cache_enable 1
12702         rm -f $DIR/$tfile
12703 }
12704 run_test 151 "test cache on oss and controls ==============================="
12705
12706 test_152() {
12707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12708
12709         local TF="$TMP/$tfile"
12710
12711         # simulate ENOMEM during write
12712 #define OBD_FAIL_OST_NOMEM      0x226
12713         lctl set_param fail_loc=0x80000226
12714         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12715         cp $TF $DIR/$tfile
12716         sync || error "sync failed"
12717         lctl set_param fail_loc=0
12718
12719         # discard client's cache
12720         cancel_lru_locks osc
12721
12722         # simulate ENOMEM during read
12723         lctl set_param fail_loc=0x80000226
12724         cmp $TF $DIR/$tfile || error "cmp failed"
12725         lctl set_param fail_loc=0
12726
12727         rm -f $TF
12728 }
12729 run_test 152 "test read/write with enomem ============================"
12730
12731 test_153() {
12732         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12733 }
12734 run_test 153 "test if fdatasync does not crash ======================="
12735
12736 dot_lustre_fid_permission_check() {
12737         local fid=$1
12738         local ffid=$MOUNT/.lustre/fid/$fid
12739         local test_dir=$2
12740
12741         echo "stat fid $fid"
12742         stat $ffid > /dev/null || error "stat $ffid failed."
12743         echo "touch fid $fid"
12744         touch $ffid || error "touch $ffid failed."
12745         echo "write to fid $fid"
12746         cat /etc/hosts > $ffid || error "write $ffid failed."
12747         echo "read fid $fid"
12748         diff /etc/hosts $ffid || error "read $ffid failed."
12749         echo "append write to fid $fid"
12750         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12751         echo "rename fid $fid"
12752         mv $ffid $test_dir/$tfile.1 &&
12753                 error "rename $ffid to $tfile.1 should fail."
12754         touch $test_dir/$tfile.1
12755         mv $test_dir/$tfile.1 $ffid &&
12756                 error "rename $tfile.1 to $ffid should fail."
12757         rm -f $test_dir/$tfile.1
12758         echo "truncate fid $fid"
12759         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12760         echo "link fid $fid"
12761         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12762         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12763                 echo "setfacl fid $fid"
12764                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12765                 echo "getfacl fid $fid"
12766                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12767         fi
12768         echo "unlink fid $fid"
12769         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12770         echo "mknod fid $fid"
12771         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12772
12773         fid=[0xf00000400:0x1:0x0]
12774         ffid=$MOUNT/.lustre/fid/$fid
12775
12776         echo "stat non-exist fid $fid"
12777         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12778         echo "write to non-exist fid $fid"
12779         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12780         echo "link new fid $fid"
12781         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12782
12783         mkdir -p $test_dir/$tdir
12784         touch $test_dir/$tdir/$tfile
12785         fid=$($LFS path2fid $test_dir/$tdir)
12786         rc=$?
12787         [ $rc -ne 0 ] &&
12788                 error "error: could not get fid for $test_dir/$dir/$tfile."
12789
12790         ffid=$MOUNT/.lustre/fid/$fid
12791
12792         echo "ls $fid"
12793         ls $ffid > /dev/null || error "ls $ffid failed."
12794         echo "touch $fid/$tfile.1"
12795         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12796
12797         echo "touch $MOUNT/.lustre/fid/$tfile"
12798         touch $MOUNT/.lustre/fid/$tfile && \
12799                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12800
12801         echo "setxattr to $MOUNT/.lustre/fid"
12802         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12803
12804         echo "listxattr for $MOUNT/.lustre/fid"
12805         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12806
12807         echo "delxattr from $MOUNT/.lustre/fid"
12808         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12809
12810         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12811         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12812                 error "touch invalid fid should fail."
12813
12814         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12815         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12816                 error "touch non-normal fid should fail."
12817
12818         echo "rename $tdir to $MOUNT/.lustre/fid"
12819         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12820                 error "rename to $MOUNT/.lustre/fid should fail."
12821
12822         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12823         then            # LU-3547
12824                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12825                 local new_obf_mode=777
12826
12827                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12828                 chmod $new_obf_mode $DIR/.lustre/fid ||
12829                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12830
12831                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12832                 [ $obf_mode -eq $new_obf_mode ] ||
12833                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12834
12835                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12836                 chmod $old_obf_mode $DIR/.lustre/fid ||
12837                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12838         fi
12839
12840         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12841         fid=$($LFS path2fid $test_dir/$tfile-2)
12842
12843         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12844         then # LU-5424
12845                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12846                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12847                         error "create lov data thru .lustre failed"
12848         fi
12849         echo "cp /etc/passwd $test_dir/$tfile-2"
12850         cp /etc/passwd $test_dir/$tfile-2 ||
12851                 error "copy to $test_dir/$tfile-2 failed."
12852         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12853         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12854                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12855
12856         rm -rf $test_dir/tfile.lnk
12857         rm -rf $test_dir/$tfile-2
12858 }
12859
12860 test_154A() {
12861         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12862                 skip "Need MDS version at least 2.4.1"
12863
12864         local tf=$DIR/$tfile
12865         touch $tf
12866
12867         local fid=$($LFS path2fid $tf)
12868         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12869
12870         # check that we get the same pathname back
12871         local found=$($LFS fid2path $MOUNT "$fid")
12872         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12873         [ "$found" == "$tf" ] ||
12874                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12875 }
12876 run_test 154A "lfs path2fid and fid2path basic checks"
12877
12878 test_154B() {
12879         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12880                 skip "Need MDS version at least 2.4.1"
12881
12882         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12883         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12884         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12885         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12886
12887         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12888         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12889
12890         # check that we get the same pathname
12891         echo "PFID: $PFID, name: $name"
12892         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12893         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12894         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12895                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12896
12897         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12898 }
12899 run_test 154B "verify the ll_decode_linkea tool"
12900
12901 test_154a() {
12902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12903         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12904         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12905                 skip "Need MDS version at least 2.2.51"
12906         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12907
12908         cp /etc/hosts $DIR/$tfile
12909
12910         fid=$($LFS path2fid $DIR/$tfile)
12911         rc=$?
12912         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
12913
12914         dot_lustre_fid_permission_check "$fid" $DIR ||
12915                 error "dot lustre permission check $fid failed"
12916
12917         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
12918
12919         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
12920
12921         touch $MOUNT/.lustre/file &&
12922                 error "creation is not allowed under .lustre"
12923
12924         mkdir $MOUNT/.lustre/dir &&
12925                 error "mkdir is not allowed under .lustre"
12926
12927         rm -rf $DIR/$tfile
12928 }
12929 run_test 154a "Open-by-FID"
12930
12931 test_154b() {
12932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12933         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12934         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12935         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12936                 skip "Need MDS version at least 2.2.51"
12937
12938         local remote_dir=$DIR/$tdir/remote_dir
12939         local MDTIDX=1
12940         local rc=0
12941
12942         mkdir -p $DIR/$tdir
12943         $LFS mkdir -i $MDTIDX $remote_dir ||
12944                 error "create remote directory failed"
12945
12946         cp /etc/hosts $remote_dir/$tfile
12947
12948         fid=$($LFS path2fid $remote_dir/$tfile)
12949         rc=$?
12950         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
12951
12952         dot_lustre_fid_permission_check "$fid" $remote_dir ||
12953                 error "dot lustre permission check $fid failed"
12954         rm -rf $DIR/$tdir
12955 }
12956 run_test 154b "Open-by-FID for remote directory"
12957
12958 test_154c() {
12959         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12960                 skip "Need MDS version at least 2.4.1"
12961
12962         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
12963         local FID1=$($LFS path2fid $DIR/$tfile.1)
12964         local FID2=$($LFS path2fid $DIR/$tfile.2)
12965         local FID3=$($LFS path2fid $DIR/$tfile.3)
12966
12967         local N=1
12968         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
12969                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
12970                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
12971                 local want=FID$N
12972                 [ "$FID" = "${!want}" ] ||
12973                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
12974                 N=$((N + 1))
12975         done
12976
12977         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
12978         do
12979                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
12980                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
12981                 N=$((N + 1))
12982         done
12983 }
12984 run_test 154c "lfs path2fid and fid2path multiple arguments"
12985
12986 test_154d() {
12987         remote_mds_nodsh && skip "remote MDS with nodsh"
12988         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
12989                 skip "Need MDS version at least 2.5.53"
12990
12991         if remote_mds; then
12992                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
12993         else
12994                 nid="0@lo"
12995         fi
12996         local proc_ofile="mdt.*.exports.'$nid'.open_files"
12997         local fd
12998         local cmd
12999
13000         rm -f $DIR/$tfile
13001         touch $DIR/$tfile
13002
13003         local fid=$($LFS path2fid $DIR/$tfile)
13004         # Open the file
13005         fd=$(free_fd)
13006         cmd="exec $fd<$DIR/$tfile"
13007         eval $cmd
13008         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13009         echo "$fid_list" | grep "$fid"
13010         rc=$?
13011
13012         cmd="exec $fd>/dev/null"
13013         eval $cmd
13014         if [ $rc -ne 0 ]; then
13015                 error "FID $fid not found in open files list $fid_list"
13016         fi
13017 }
13018 run_test 154d "Verify open file fid"
13019
13020 test_154e()
13021 {
13022         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13023                 skip "Need MDS version at least 2.6.50"
13024
13025         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13026                 error ".lustre returned by readdir"
13027         fi
13028 }
13029 run_test 154e ".lustre is not returned by readdir"
13030
13031 test_154f() {
13032         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13033
13034         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13035         test_mkdir -p -c1 $DIR/$tdir/d
13036         # test dirs inherit from its stripe
13037         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13038         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13039         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13040         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13041         touch $DIR/f
13042
13043         # get fid of parents
13044         local FID0=$($LFS path2fid $DIR/$tdir/d)
13045         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13046         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13047         local FID3=$($LFS path2fid $DIR)
13048
13049         # check that path2fid --parents returns expected <parent_fid>/name
13050         # 1) test for a directory (single parent)
13051         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13052         [ "$parent" == "$FID0/foo1" ] ||
13053                 error "expected parent: $FID0/foo1, got: $parent"
13054
13055         # 2) test for a file with nlink > 1 (multiple parents)
13056         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13057         echo "$parent" | grep -F "$FID1/$tfile" ||
13058                 error "$FID1/$tfile not returned in parent list"
13059         echo "$parent" | grep -F "$FID2/link" ||
13060                 error "$FID2/link not returned in parent list"
13061
13062         # 3) get parent by fid
13063         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13064         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13065         echo "$parent" | grep -F "$FID1/$tfile" ||
13066                 error "$FID1/$tfile not returned in parent list (by fid)"
13067         echo "$parent" | grep -F "$FID2/link" ||
13068                 error "$FID2/link not returned in parent list (by fid)"
13069
13070         # 4) test for entry in root directory
13071         parent=$($LFS path2fid --parents $DIR/f)
13072         echo "$parent" | grep -F "$FID3/f" ||
13073                 error "$FID3/f not returned in parent list"
13074
13075         # 5) test it on root directory
13076         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13077                 error "$MOUNT should not have parents"
13078
13079         # enable xattr caching and check that linkea is correctly updated
13080         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13081         save_lustre_params client "llite.*.xattr_cache" > $save
13082         lctl set_param llite.*.xattr_cache 1
13083
13084         # 6.1) linkea update on rename
13085         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13086
13087         # get parents by fid
13088         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13089         # foo1 should no longer be returned in parent list
13090         echo "$parent" | grep -F "$FID1" &&
13091                 error "$FID1 should no longer be in parent list"
13092         # the new path should appear
13093         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13094                 error "$FID2/$tfile.moved is not in parent list"
13095
13096         # 6.2) linkea update on unlink
13097         rm -f $DIR/$tdir/d/foo2/link
13098         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13099         # foo2/link should no longer be returned in parent list
13100         echo "$parent" | grep -F "$FID2/link" &&
13101                 error "$FID2/link should no longer be in parent list"
13102         true
13103
13104         rm -f $DIR/f
13105         restore_lustre_params < $save
13106         rm -f $save
13107 }
13108 run_test 154f "get parent fids by reading link ea"
13109
13110 test_154g()
13111 {
13112         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13113         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13114            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13115                 skip "Need MDS version at least 2.6.92"
13116
13117         mkdir -p $DIR/$tdir
13118         llapi_fid_test -d $DIR/$tdir
13119 }
13120 run_test 154g "various llapi FID tests"
13121
13122 test_155_small_load() {
13123     local temp=$TMP/$tfile
13124     local file=$DIR/$tfile
13125
13126     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13127         error "dd of=$temp bs=6096 count=1 failed"
13128     cp $temp $file
13129     cancel_lru_locks $OSC
13130     cmp $temp $file || error "$temp $file differ"
13131
13132     $TRUNCATE $temp 6000
13133     $TRUNCATE $file 6000
13134     cmp $temp $file || error "$temp $file differ (truncate1)"
13135
13136     echo "12345" >>$temp
13137     echo "12345" >>$file
13138     cmp $temp $file || error "$temp $file differ (append1)"
13139
13140     echo "12345" >>$temp
13141     echo "12345" >>$file
13142     cmp $temp $file || error "$temp $file differ (append2)"
13143
13144     rm -f $temp $file
13145     true
13146 }
13147
13148 test_155_big_load() {
13149         remote_ost_nodsh && skip "remote OST with nodsh"
13150
13151         local temp=$TMP/$tfile
13152         local file=$DIR/$tfile
13153
13154         free_min_max
13155         local cache_size=$(do_facet ost$((MAXI+1)) \
13156                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13157         local large_file_size=$((cache_size * 2))
13158
13159         echo "OSS cache size: $cache_size KB"
13160         echo "Large file size: $large_file_size KB"
13161
13162         [ $MAXV -le $large_file_size ] &&
13163                 skip_env "max available OST size needs > $large_file_size KB"
13164
13165         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13166
13167         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13168                 error "dd of=$temp bs=$large_file_size count=1k failed"
13169         cp $temp $file
13170         ls -lh $temp $file
13171         cancel_lru_locks osc
13172         cmp $temp $file || error "$temp $file differ"
13173
13174         rm -f $temp $file
13175         true
13176 }
13177
13178 save_writethrough() {
13179         local facets=$(get_facets OST)
13180
13181         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13182 }
13183
13184 test_155a() {
13185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13186
13187         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13188
13189         save_writethrough $p
13190
13191         set_cache read on
13192         set_cache writethrough on
13193         test_155_small_load
13194         restore_lustre_params < $p
13195         rm -f $p
13196 }
13197 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13198
13199 test_155b() {
13200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13201
13202         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13203
13204         save_writethrough $p
13205
13206         set_cache read on
13207         set_cache writethrough off
13208         test_155_small_load
13209         restore_lustre_params < $p
13210         rm -f $p
13211 }
13212 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13213
13214 test_155c() {
13215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13216
13217         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13218
13219         save_writethrough $p
13220
13221         set_cache read off
13222         set_cache writethrough on
13223         test_155_small_load
13224         restore_lustre_params < $p
13225         rm -f $p
13226 }
13227 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13228
13229 test_155d() {
13230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13231
13232         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13233
13234         save_writethrough $p
13235
13236         set_cache read off
13237         set_cache writethrough off
13238         test_155_small_load
13239         restore_lustre_params < $p
13240         rm -f $p
13241 }
13242 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
13243
13244 test_155e() {
13245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13246
13247         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13248
13249         save_writethrough $p
13250
13251         set_cache read on
13252         set_cache writethrough on
13253         test_155_big_load
13254         restore_lustre_params < $p
13255         rm -f $p
13256 }
13257 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
13258
13259 test_155f() {
13260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13261
13262         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13263
13264         save_writethrough $p
13265
13266         set_cache read on
13267         set_cache writethrough off
13268         test_155_big_load
13269         restore_lustre_params < $p
13270         rm -f $p
13271 }
13272 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
13273
13274 test_155g() {
13275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13276
13277         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13278
13279         save_writethrough $p
13280
13281         set_cache read off
13282         set_cache writethrough on
13283         test_155_big_load
13284         restore_lustre_params < $p
13285         rm -f $p
13286 }
13287 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
13288
13289 test_155h() {
13290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13291
13292         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13293
13294         save_writethrough $p
13295
13296         set_cache read off
13297         set_cache writethrough off
13298         test_155_big_load
13299         restore_lustre_params < $p
13300         rm -f $p
13301 }
13302 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
13303
13304 test_156() {
13305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13306         remote_ost_nodsh && skip "remote OST with nodsh"
13307         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
13308                 skip "stats not implemented on old servers"
13309         [ "$ost1_FSTYPE" = "zfs" ] &&
13310                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
13311
13312         local CPAGES=3
13313         local BEFORE
13314         local AFTER
13315         local file="$DIR/$tfile"
13316         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13317
13318         save_writethrough $p
13319         roc_hit_init
13320
13321         log "Turn on read and write cache"
13322         set_cache read on
13323         set_cache writethrough on
13324
13325         log "Write data and read it back."
13326         log "Read should be satisfied from the cache."
13327         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13328         BEFORE=$(roc_hit)
13329         cancel_lru_locks osc
13330         cat $file >/dev/null
13331         AFTER=$(roc_hit)
13332         if ! let "AFTER - BEFORE == CPAGES"; then
13333                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13334         else
13335                 log "cache hits:: before: $BEFORE, after: $AFTER"
13336         fi
13337
13338         log "Read again; it should be satisfied from the cache."
13339         BEFORE=$AFTER
13340         cancel_lru_locks osc
13341         cat $file >/dev/null
13342         AFTER=$(roc_hit)
13343         if ! let "AFTER - BEFORE == CPAGES"; then
13344                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13345         else
13346                 log "cache hits:: before: $BEFORE, after: $AFTER"
13347         fi
13348
13349         log "Turn off the read cache and turn on the write cache"
13350         set_cache read off
13351         set_cache writethrough on
13352
13353         log "Read again; it should be satisfied from the cache."
13354         BEFORE=$(roc_hit)
13355         cancel_lru_locks osc
13356         cat $file >/dev/null
13357         AFTER=$(roc_hit)
13358         if ! let "AFTER - BEFORE == CPAGES"; then
13359                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13360         else
13361                 log "cache hits:: before: $BEFORE, after: $AFTER"
13362         fi
13363
13364         log "Read again; it should not be satisfied from the cache."
13365         BEFORE=$AFTER
13366         cancel_lru_locks osc
13367         cat $file >/dev/null
13368         AFTER=$(roc_hit)
13369         if ! let "AFTER - BEFORE == 0"; then
13370                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13371         else
13372                 log "cache hits:: before: $BEFORE, after: $AFTER"
13373         fi
13374
13375         log "Write data and read it back."
13376         log "Read should be satisfied from the cache."
13377         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13378         BEFORE=$(roc_hit)
13379         cancel_lru_locks osc
13380         cat $file >/dev/null
13381         AFTER=$(roc_hit)
13382         if ! let "AFTER - BEFORE == CPAGES"; then
13383                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13384         else
13385                 log "cache hits:: before: $BEFORE, after: $AFTER"
13386         fi
13387
13388         log "Read again; it should not be satisfied from the cache."
13389         BEFORE=$AFTER
13390         cancel_lru_locks osc
13391         cat $file >/dev/null
13392         AFTER=$(roc_hit)
13393         if ! let "AFTER - BEFORE == 0"; then
13394                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13395         else
13396                 log "cache hits:: before: $BEFORE, after: $AFTER"
13397         fi
13398
13399         log "Turn off read and write cache"
13400         set_cache read off
13401         set_cache writethrough off
13402
13403         log "Write data and read it back"
13404         log "It should not be satisfied from the cache."
13405         rm -f $file
13406         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13407         cancel_lru_locks osc
13408         BEFORE=$(roc_hit)
13409         cat $file >/dev/null
13410         AFTER=$(roc_hit)
13411         if ! let "AFTER - BEFORE == 0"; then
13412                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
13413         else
13414                 log "cache hits:: before: $BEFORE, after: $AFTER"
13415         fi
13416
13417         log "Turn on the read cache and turn off the write cache"
13418         set_cache read on
13419         set_cache writethrough off
13420
13421         log "Write data and read it back"
13422         log "It should not be satisfied from the cache."
13423         rm -f $file
13424         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13425         BEFORE=$(roc_hit)
13426         cancel_lru_locks osc
13427         cat $file >/dev/null
13428         AFTER=$(roc_hit)
13429         if ! let "AFTER - BEFORE == 0"; then
13430                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
13431         else
13432                 log "cache hits:: before: $BEFORE, after: $AFTER"
13433         fi
13434
13435         log "Read again; it should be satisfied from the cache."
13436         BEFORE=$(roc_hit)
13437         cancel_lru_locks osc
13438         cat $file >/dev/null
13439         AFTER=$(roc_hit)
13440         if ! let "AFTER - BEFORE == CPAGES"; then
13441                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13442         else
13443                 log "cache hits:: before: $BEFORE, after: $AFTER"
13444         fi
13445
13446         restore_lustre_params < $p
13447         rm -f $p $file
13448 }
13449 run_test 156 "Verification of tunables"
13450
13451 test_160a() {
13452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13453         remote_mds_nodsh && skip "remote MDS with nodsh"
13454         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13455                 skip "Need MDS version at least 2.2.0"
13456
13457         changelog_register || error "changelog_register failed"
13458         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13459         changelog_users $SINGLEMDS | grep -q $cl_user ||
13460                 error "User $cl_user not found in changelog_users"
13461
13462         # change something
13463         test_mkdir -p $DIR/$tdir/pics/2008/zachy
13464         changelog_clear 0 || error "changelog_clear failed"
13465         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
13466         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
13467         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
13468         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
13469         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
13470         rm $DIR/$tdir/pics/desktop.jpg
13471
13472         changelog_dump | tail -10
13473
13474         echo "verifying changelog mask"
13475         changelog_chmask "-MKDIR"
13476         changelog_chmask "-CLOSE"
13477
13478         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
13479         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
13480
13481         changelog_chmask "+MKDIR"
13482         changelog_chmask "+CLOSE"
13483
13484         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
13485         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13486
13487         changelog_dump | tail -10
13488         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13489         CLOSES=$(changelog_dump | grep -c "CLOSE")
13490         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13491         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13492
13493         # verify contents
13494         echo "verifying target fid"
13495         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13496         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13497         [ "$fidc" == "$fidf" ] ||
13498                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13499         echo "verifying parent fid"
13500         # The FID returned from the Changelog may be the directory shard on
13501         # a different MDT, and not the FID returned by path2fid on the parent.
13502         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13503         # since this is what will matter when recreating this file in the tree.
13504         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13505         local pathp=$($LFS fid2path $MOUNT "$fidp")
13506         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13507                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13508
13509         echo "getting records for $cl_user"
13510         changelog_users $SINGLEMDS
13511         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13512         local nclr=3
13513         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13514                 error "changelog_clear failed"
13515         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13516         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13517         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13518                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13519
13520         local min0_rec=$(changelog_users $SINGLEMDS |
13521                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13522         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13523                           awk '{ print $1; exit; }')
13524
13525         changelog_dump | tail -n 5
13526         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13527         [ $first_rec == $((min0_rec + 1)) ] ||
13528                 error "first index should be $min0_rec + 1 not $first_rec"
13529
13530         # LU-3446 changelog index reset on MDT restart
13531         local cur_rec1=$(changelog_users $SINGLEMDS |
13532                          awk '/^current.index:/ { print $NF }')
13533         changelog_clear 0 ||
13534                 error "clear all changelog records for $cl_user failed"
13535         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13536         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13537                 error "Fail to start $SINGLEMDS"
13538         local cur_rec2=$(changelog_users $SINGLEMDS |
13539                          awk '/^current.index:/ { print $NF }')
13540         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13541         [ $cur_rec1 == $cur_rec2 ] ||
13542                 error "current index should be $cur_rec1 not $cur_rec2"
13543
13544         echo "verifying users from this test are deregistered"
13545         changelog_deregister || error "changelog_deregister failed"
13546         changelog_users $SINGLEMDS | grep -q $cl_user &&
13547                 error "User '$cl_user' still in changelog_users"
13548
13549         # lctl get_param -n mdd.*.changelog_users
13550         # current index: 144
13551         # ID    index (idle seconds)
13552         # cl3   144 (2)
13553         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13554                 # this is the normal case where all users were deregistered
13555                 # make sure no new records are added when no users are present
13556                 local last_rec1=$(changelog_users $SINGLEMDS |
13557                                   awk '/^current.index:/ { print $NF }')
13558                 touch $DIR/$tdir/chloe
13559                 local last_rec2=$(changelog_users $SINGLEMDS |
13560                                   awk '/^current.index:/ { print $NF }')
13561                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13562                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13563         else
13564                 # any changelog users must be leftovers from a previous test
13565                 changelog_users $SINGLEMDS
13566                 echo "other changelog users; can't verify off"
13567         fi
13568 }
13569 run_test 160a "changelog sanity"
13570
13571 test_160b() { # LU-3587
13572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13573         remote_mds_nodsh && skip "remote MDS with nodsh"
13574         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13575                 skip "Need MDS version at least 2.2.0"
13576
13577         changelog_register || error "changelog_register failed"
13578         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13579         changelog_users $SINGLEMDS | grep -q $cl_user ||
13580                 error "User '$cl_user' not found in changelog_users"
13581
13582         local longname1=$(str_repeat a 255)
13583         local longname2=$(str_repeat b 255)
13584
13585         cd $DIR
13586         echo "creating very long named file"
13587         touch $longname1 || error "create of '$longname1' failed"
13588         echo "renaming very long named file"
13589         mv $longname1 $longname2
13590
13591         changelog_dump | grep RENME | tail -n 5
13592         rm -f $longname2
13593 }
13594 run_test 160b "Verify that very long rename doesn't crash in changelog"
13595
13596 test_160c() {
13597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13598         remote_mds_nodsh && skip "remote MDS with nodsh"
13599
13600         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13601                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13602                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13603                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13604
13605         local rc=0
13606
13607         # Registration step
13608         changelog_register || error "changelog_register failed"
13609
13610         rm -rf $DIR/$tdir
13611         mkdir -p $DIR/$tdir
13612         $MCREATE $DIR/$tdir/foo_160c
13613         changelog_chmask "-TRUNC"
13614         $TRUNCATE $DIR/$tdir/foo_160c 200
13615         changelog_chmask "+TRUNC"
13616         $TRUNCATE $DIR/$tdir/foo_160c 199
13617         changelog_dump | tail -n 5
13618         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13619         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13620 }
13621 run_test 160c "verify that changelog log catch the truncate event"
13622
13623 test_160d() {
13624         remote_mds_nodsh && skip "remote MDS with nodsh"
13625         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13627         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13628                 skip "Need MDS version at least 2.7.60"
13629
13630         # Registration step
13631         changelog_register || error "changelog_register failed"
13632
13633         mkdir -p $DIR/$tdir/migrate_dir
13634         changelog_clear 0 || error "changelog_clear failed"
13635
13636         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13637         changelog_dump | tail -n 5
13638         local migrates=$(changelog_dump | grep -c "MIGRT")
13639         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13640 }
13641 run_test 160d "verify that changelog log catch the migrate event"
13642
13643 test_160e() {
13644         remote_mds_nodsh && skip "remote MDS with nodsh"
13645
13646         # Create a user
13647         changelog_register || error "changelog_register failed"
13648
13649         # Delete a future user (expect fail)
13650         local MDT0=$(facet_svc $SINGLEMDS)
13651         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13652         local rc=$?
13653
13654         if [ $rc -eq 0 ]; then
13655                 error "Deleted non-existant user cl77"
13656         elif [ $rc -ne 2 ]; then
13657                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13658         fi
13659
13660         # Clear to a bad index (1 billion should be safe)
13661         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13662         rc=$?
13663
13664         if [ $rc -eq 0 ]; then
13665                 error "Successfully cleared to invalid CL index"
13666         elif [ $rc -ne 22 ]; then
13667                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13668         fi
13669 }
13670 run_test 160e "changelog negative testing (should return errors)"
13671
13672 test_160f() {
13673         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13674         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13675                 skip "Need MDS version at least 2.10.56"
13676
13677         local mdts=$(comma_list $(mdts_nodes))
13678
13679         # Create a user
13680         changelog_register || error "first changelog_register failed"
13681         changelog_register || error "second changelog_register failed"
13682         local cl_users
13683         declare -A cl_user1
13684         declare -A cl_user2
13685         local user_rec1
13686         local user_rec2
13687         local i
13688
13689         # generate some changelog records to accumulate on each MDT
13690         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13691         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13692                 error "create $DIR/$tdir/$tfile failed"
13693
13694         # check changelogs have been generated
13695         local nbcl=$(changelog_dump | wc -l)
13696         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13697
13698         for param in "changelog_max_idle_time=10" \
13699                      "changelog_gc=1" \
13700                      "changelog_min_gc_interval=2" \
13701                      "changelog_min_free_cat_entries=3"; do
13702                 local MDT0=$(facet_svc $SINGLEMDS)
13703                 local var="${param%=*}"
13704                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13705
13706                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13707                 do_nodes $mdts $LCTL set_param mdd.*.$param
13708         done
13709
13710         # force cl_user2 to be idle (1st part)
13711         sleep 9
13712
13713         # simulate changelog catalog almost full
13714         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13715         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13716
13717         for i in $(seq $MDSCOUNT); do
13718                 cl_users=(${CL_USERS[mds$i]})
13719                 cl_user1[mds$i]="${cl_users[0]}"
13720                 cl_user2[mds$i]="${cl_users[1]}"
13721
13722                 [ -n "${cl_user1[mds$i]}" ] ||
13723                         error "mds$i: no user registered"
13724                 [ -n "${cl_user2[mds$i]}" ] ||
13725                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13726
13727                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13728                 [ -n "$user_rec1" ] ||
13729                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13730                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13731                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13732                 [ -n "$user_rec2" ] ||
13733                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13734                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13735                      "$user_rec1 + 2 == $user_rec2"
13736                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13737                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13738                               "$user_rec1 + 2, but is $user_rec2"
13739                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13740                 [ -n "$user_rec2" ] ||
13741                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13742                 [ $user_rec1 == $user_rec2 ] ||
13743                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13744                               "$user_rec1, but is $user_rec2"
13745         done
13746
13747         # force cl_user2 to be idle (2nd part) and to reach
13748         # changelog_max_idle_time
13749         sleep 2
13750
13751         # generate one more changelog to trigger fail_loc
13752         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13753                 error "create $DIR/$tdir/${tfile}bis failed"
13754
13755         # ensure gc thread is done
13756         for i in $(mdts_nodes); do
13757                 wait_update $i \
13758                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13759                         error "$i: GC-thread not done"
13760         done
13761
13762         local first_rec
13763         for i in $(seq $MDSCOUNT); do
13764                 # check cl_user1 still registered
13765                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13766                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13767                 # check cl_user2 unregistered
13768                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13769                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13770
13771                 # check changelogs are present and starting at $user_rec1 + 1
13772                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13773                 [ -n "$user_rec1" ] ||
13774                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13775                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13776                             awk '{ print $1; exit; }')
13777
13778                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13779                 [ $((user_rec1 + 1)) == $first_rec ] ||
13780                         error "mds$i: first index should be $user_rec1 + 1, " \
13781                               "but is $first_rec"
13782         done
13783 }
13784 run_test 160f "changelog garbage collect (timestamped users)"
13785
13786 test_160g() {
13787         remote_mds_nodsh && skip "remote MDS with nodsh"
13788         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13789                 skip "Need MDS version at least 2.10.56"
13790
13791         local mdts=$(comma_list $(mdts_nodes))
13792
13793         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13794         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13795
13796         # Create a user
13797         changelog_register || error "first changelog_register failed"
13798         changelog_register || error "second changelog_register failed"
13799         local cl_users
13800         declare -A cl_user1
13801         declare -A cl_user2
13802         local user_rec1
13803         local user_rec2
13804         local i
13805
13806         # generate some changelog records to accumulate on each MDT
13807         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13808         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13809                 error "create $DIR/$tdir/$tfile failed"
13810
13811         # check changelogs have been generated
13812         local nbcl=$(changelog_dump | wc -l)
13813         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13814
13815         # reduce the max_idle_indexes value to make sure we exceed it
13816         max_ndx=$((nbcl / 2 - 1))
13817
13818         for param in "changelog_max_idle_indexes=$max_ndx" \
13819                      "changelog_gc=1" \
13820                      "changelog_min_gc_interval=2" \
13821                      "changelog_min_free_cat_entries=3"; do
13822                 local MDT0=$(facet_svc $SINGLEMDS)
13823                 local var="${param%=*}"
13824                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13825
13826                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13827                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13828                         error "unable to set mdd.*.$param"
13829         done
13830
13831         # simulate changelog catalog almost full
13832         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13833         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13834
13835         for i in $(seq $MDSCOUNT); do
13836                 cl_users=(${CL_USERS[mds$i]})
13837                 cl_user1[mds$i]="${cl_users[0]}"
13838                 cl_user2[mds$i]="${cl_users[1]}"
13839
13840                 [ -n "${cl_user1[mds$i]}" ] ||
13841                         error "mds$i: no user registered"
13842                 [ -n "${cl_user2[mds$i]}" ] ||
13843                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13844
13845                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13846                 [ -n "$user_rec1" ] ||
13847                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13848                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13849                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13850                 [ -n "$user_rec2" ] ||
13851                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13852                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13853                      "$user_rec1 + 2 == $user_rec2"
13854                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13855                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13856                               "$user_rec1 + 2, but is $user_rec2"
13857                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13858                 [ -n "$user_rec2" ] ||
13859                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13860                 [ $user_rec1 == $user_rec2 ] ||
13861                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13862                               "$user_rec1, but is $user_rec2"
13863         done
13864
13865         # ensure we are past the previous changelog_min_gc_interval set above
13866         sleep 2
13867
13868         # generate one more changelog to trigger fail_loc
13869         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13870                 error "create $DIR/$tdir/${tfile}bis failed"
13871
13872         # ensure gc thread is done
13873         for i in $(mdts_nodes); do
13874                 wait_update $i \
13875                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13876                         error "$i: GC-thread not done"
13877         done
13878
13879         local first_rec
13880         for i in $(seq $MDSCOUNT); do
13881                 # check cl_user1 still registered
13882                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13883                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13884                 # check cl_user2 unregistered
13885                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13886                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13887
13888                 # check changelogs are present and starting at $user_rec1 + 1
13889                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13890                 [ -n "$user_rec1" ] ||
13891                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13892                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13893                             awk '{ print $1; exit; }')
13894
13895                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13896                 [ $((user_rec1 + 1)) == $first_rec ] ||
13897                         error "mds$i: first index should be $user_rec1 + 1, " \
13898                               "but is $first_rec"
13899         done
13900 }
13901 run_test 160g "changelog garbage collect (old users)"
13902
13903 test_160h() {
13904         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13905         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13906                 skip "Need MDS version at least 2.10.56"
13907
13908         local mdts=$(comma_list $(mdts_nodes))
13909
13910         # Create a user
13911         changelog_register || error "first changelog_register failed"
13912         changelog_register || error "second changelog_register failed"
13913         local cl_users
13914         declare -A cl_user1
13915         declare -A cl_user2
13916         local user_rec1
13917         local user_rec2
13918         local i
13919
13920         # generate some changelog records to accumulate on each MDT
13921         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13922         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13923                 error "create $DIR/$tdir/$tfile failed"
13924
13925         # check changelogs have been generated
13926         local nbcl=$(changelog_dump | wc -l)
13927         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13928
13929         for param in "changelog_max_idle_time=10" \
13930                      "changelog_gc=1" \
13931                      "changelog_min_gc_interval=2"; do
13932                 local MDT0=$(facet_svc $SINGLEMDS)
13933                 local var="${param%=*}"
13934                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13935
13936                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13937                 do_nodes $mdts $LCTL set_param mdd.*.$param
13938         done
13939
13940         # force cl_user2 to be idle (1st part)
13941         sleep 9
13942
13943         for i in $(seq $MDSCOUNT); do
13944                 cl_users=(${CL_USERS[mds$i]})
13945                 cl_user1[mds$i]="${cl_users[0]}"
13946                 cl_user2[mds$i]="${cl_users[1]}"
13947
13948                 [ -n "${cl_user1[mds$i]}" ] ||
13949                         error "mds$i: no user registered"
13950                 [ -n "${cl_user2[mds$i]}" ] ||
13951                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13952
13953                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13954                 [ -n "$user_rec1" ] ||
13955                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13956                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13957                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13958                 [ -n "$user_rec2" ] ||
13959                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13960                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13961                      "$user_rec1 + 2 == $user_rec2"
13962                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13963                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13964                               "$user_rec1 + 2, but is $user_rec2"
13965                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13966                 [ -n "$user_rec2" ] ||
13967                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13968                 [ $user_rec1 == $user_rec2 ] ||
13969                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13970                               "$user_rec1, but is $user_rec2"
13971         done
13972
13973         # force cl_user2 to be idle (2nd part) and to reach
13974         # changelog_max_idle_time
13975         sleep 2
13976
13977         # force each GC-thread start and block then
13978         # one per MDT/MDD, set fail_val accordingly
13979         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
13980         do_nodes $mdts $LCTL set_param fail_loc=0x1316
13981
13982         # generate more changelogs to trigger fail_loc
13983         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13984                 error "create $DIR/$tdir/${tfile}bis failed"
13985
13986         # stop MDT to stop GC-thread, should be done in back-ground as it will
13987         # block waiting for the thread to be released and exit
13988         declare -A stop_pids
13989         for i in $(seq $MDSCOUNT); do
13990                 stop mds$i &
13991                 stop_pids[mds$i]=$!
13992         done
13993
13994         for i in $(mdts_nodes); do
13995                 local facet
13996                 local nb=0
13997                 local facets=$(facets_up_on_host $i)
13998
13999                 for facet in ${facets//,/ }; do
14000                         if [[ $facet == mds* ]]; then
14001                                 nb=$((nb + 1))
14002                         fi
14003                 done
14004                 # ensure each MDS's gc threads are still present and all in "R"
14005                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14006                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14007                         error "$i: expected $nb GC-thread"
14008                 wait_update $i \
14009                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14010                         "R" 20 ||
14011                         error "$i: GC-thread not found in R-state"
14012                 # check umounts of each MDT on MDS have reached kthread_stop()
14013                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14014                         error "$i: expected $nb umount"
14015                 wait_update $i \
14016                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14017                         error "$i: umount not found in D-state"
14018         done
14019
14020         # release all GC-threads
14021         do_nodes $mdts $LCTL set_param fail_loc=0
14022
14023         # wait for MDT stop to complete
14024         for i in $(seq $MDSCOUNT); do
14025                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14026         done
14027
14028         # XXX
14029         # may try to check if any orphan changelog records are present
14030         # via ldiskfs/zfs and llog_reader...
14031
14032         # re-start/mount MDTs
14033         for i in $(seq $MDSCOUNT); do
14034                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14035                         error "Fail to start mds$i"
14036         done
14037
14038         local first_rec
14039         for i in $(seq $MDSCOUNT); do
14040                 # check cl_user1 still registered
14041                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14042                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14043                 # check cl_user2 unregistered
14044                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14045                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14046
14047                 # check changelogs are present and starting at $user_rec1 + 1
14048                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14049                 [ -n "$user_rec1" ] ||
14050                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14051                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14052                             awk '{ print $1; exit; }')
14053
14054                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14055                 [ $((user_rec1 + 1)) == $first_rec ] ||
14056                         error "mds$i: first index should be $user_rec1 + 1, " \
14057                               "but is $first_rec"
14058         done
14059 }
14060 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14061               "during mount"
14062
14063 test_160i() {
14064
14065         local mdts=$(comma_list $(mdts_nodes))
14066
14067         changelog_register || error "first changelog_register failed"
14068
14069         # generate some changelog records to accumulate on each MDT
14070         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14071         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14072                 error "create $DIR/$tdir/$tfile failed"
14073
14074         # check changelogs have been generated
14075         local nbcl=$(changelog_dump | wc -l)
14076         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14077
14078         # simulate race between register and unregister
14079         # XXX as fail_loc is set per-MDS, with DNE configs the race
14080         # simulation will only occur for one MDT per MDS and for the
14081         # others the normal race scenario will take place
14082         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14083         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14084         do_nodes $mdts $LCTL set_param fail_val=1
14085
14086         # unregister 1st user
14087         changelog_deregister &
14088         local pid1=$!
14089         # wait some time for deregister work to reach race rdv
14090         sleep 2
14091         # register 2nd user
14092         changelog_register || error "2nd user register failed"
14093
14094         wait $pid1 || error "1st user deregister failed"
14095
14096         local i
14097         local last_rec
14098         declare -A LAST_REC
14099         for i in $(seq $MDSCOUNT); do
14100                 if changelog_users mds$i | grep "^cl"; then
14101                         # make sure new records are added with one user present
14102                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14103                                           awk '/^current.index:/ { print $NF }')
14104                 else
14105                         error "mds$i has no user registered"
14106                 fi
14107         done
14108
14109         # generate more changelog records to accumulate on each MDT
14110         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14111                 error "create $DIR/$tdir/${tfile}bis failed"
14112
14113         for i in $(seq $MDSCOUNT); do
14114                 last_rec=$(changelog_users $SINGLEMDS |
14115                            awk '/^current.index:/ { print $NF }')
14116                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14117                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14118                         error "changelogs are off on mds$i"
14119         done
14120 }
14121 run_test 160i "changelog user register/unregister race"
14122
14123 test_160j() {
14124         remote_mds_nodsh && skip "remote MDS with nodsh"
14125         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14126                 skip "Need MDS version at least 2.12.56"
14127
14128         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14129
14130         changelog_register || error "first changelog_register failed"
14131
14132         # generate some changelog
14133         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14134         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14135                 error "create $DIR/$tdir/${tfile}bis failed"
14136
14137         # open the changelog device
14138         exec 3>/dev/changelog-$FSNAME-MDT0000
14139         exec 4</dev/changelog-$FSNAME-MDT0000
14140
14141         # umount the first lustre mount
14142         umount $MOUNT
14143
14144         # read changelog
14145         cat <&4 >/dev/null || error "read changelog failed"
14146
14147         # clear changelog
14148         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14149         changelog_users $SINGLEMDS | grep -q $cl_user ||
14150                 error "User $cl_user not found in changelog_users"
14151
14152         printf 'clear:'$cl_user':0' >&3
14153
14154         # close
14155         exec 3>&-
14156         exec 4<&-
14157
14158         # cleanup
14159         changelog_deregister || error "changelog_deregister failed"
14160
14161         umount $MOUNT2
14162         mount_client $MOUNT || error "mount_client on $MOUNT failed"
14163 }
14164 run_test 160j "client can be umounted  while its chanangelog is being used"
14165
14166 test_160k() {
14167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14168         remote_mds_nodsh && skip "remote MDS with nodsh"
14169
14170         mkdir -p $DIR/$tdir/1/1
14171
14172         changelog_register || error "changelog_register failed"
14173         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14174
14175         changelog_users $SINGLEMDS | grep -q $cl_user ||
14176                 error "User '$cl_user' not found in changelog_users"
14177 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14178         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14179         rmdir $DIR/$tdir/1/1 & sleep 1
14180         mkdir $DIR/$tdir/2
14181         touch $DIR/$tdir/2/2
14182         rm -rf $DIR/$tdir/2
14183
14184         wait
14185         sleep 4
14186
14187         changelog_dump | grep rmdir || error "rmdir not recorded"
14188
14189         rm -rf $DIR/$tdir
14190         changelog_deregister
14191 }
14192 run_test 160k "Verify that changelog records are not lost"
14193
14194 test_161a() {
14195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14196
14197         test_mkdir -c1 $DIR/$tdir
14198         cp /etc/hosts $DIR/$tdir/$tfile
14199         test_mkdir -c1 $DIR/$tdir/foo1
14200         test_mkdir -c1 $DIR/$tdir/foo2
14201         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14202         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14203         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14204         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14205         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14206         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14207                 $LFS fid2path $DIR $FID
14208                 error "bad link ea"
14209         fi
14210         # middle
14211         rm $DIR/$tdir/foo2/zachary
14212         # last
14213         rm $DIR/$tdir/foo2/thor
14214         # first
14215         rm $DIR/$tdir/$tfile
14216         # rename
14217         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
14218         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
14219                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
14220         rm $DIR/$tdir/foo2/maggie
14221
14222         # overflow the EA
14223         local longname=$tfile.avg_len_is_thirty_two_
14224         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
14225                 error_noexit 'failed to unlink many hardlinks'" EXIT
14226         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
14227                 error "failed to hardlink many files"
14228         links=$($LFS fid2path $DIR $FID | wc -l)
14229         echo -n "${links}/1000 links in link EA"
14230         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
14231 }
14232 run_test 161a "link ea sanity"
14233
14234 test_161b() {
14235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14236         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
14237
14238         local MDTIDX=1
14239         local remote_dir=$DIR/$tdir/remote_dir
14240
14241         mkdir -p $DIR/$tdir
14242         $LFS mkdir -i $MDTIDX $remote_dir ||
14243                 error "create remote directory failed"
14244
14245         cp /etc/hosts $remote_dir/$tfile
14246         mkdir -p $remote_dir/foo1
14247         mkdir -p $remote_dir/foo2
14248         ln $remote_dir/$tfile $remote_dir/foo1/sofia
14249         ln $remote_dir/$tfile $remote_dir/foo2/zachary
14250         ln $remote_dir/$tfile $remote_dir/foo1/luna
14251         ln $remote_dir/$tfile $remote_dir/foo2/thor
14252
14253         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
14254                      tr -d ']')
14255         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14256                 $LFS fid2path $DIR $FID
14257                 error "bad link ea"
14258         fi
14259         # middle
14260         rm $remote_dir/foo2/zachary
14261         # last
14262         rm $remote_dir/foo2/thor
14263         # first
14264         rm $remote_dir/$tfile
14265         # rename
14266         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
14267         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
14268         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
14269                 $LFS fid2path $DIR $FID
14270                 error "bad link rename"
14271         fi
14272         rm $remote_dir/foo2/maggie
14273
14274         # overflow the EA
14275         local longname=filename_avg_len_is_thirty_two_
14276         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
14277                 error "failed to hardlink many files"
14278         links=$($LFS fid2path $DIR $FID | wc -l)
14279         echo -n "${links}/1000 links in link EA"
14280         [[ ${links} -gt 60 ]] ||
14281                 error "expected at least 60 links in link EA"
14282         unlinkmany $remote_dir/foo2/$longname 1000 ||
14283         error "failed to unlink many hardlinks"
14284 }
14285 run_test 161b "link ea sanity under remote directory"
14286
14287 test_161c() {
14288         remote_mds_nodsh && skip "remote MDS with nodsh"
14289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14290         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
14291                 skip "Need MDS version at least 2.1.5"
14292
14293         # define CLF_RENAME_LAST 0x0001
14294         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
14295         changelog_register || error "changelog_register failed"
14296
14297         rm -rf $DIR/$tdir
14298         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
14299         touch $DIR/$tdir/foo_161c
14300         touch $DIR/$tdir/bar_161c
14301         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14302         changelog_dump | grep RENME | tail -n 5
14303         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14304         changelog_clear 0 || error "changelog_clear failed"
14305         if [ x$flags != "x0x1" ]; then
14306                 error "flag $flags is not 0x1"
14307         fi
14308
14309         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
14310         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
14311         touch $DIR/$tdir/foo_161c
14312         touch $DIR/$tdir/bar_161c
14313         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14314         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14315         changelog_dump | grep RENME | tail -n 5
14316         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14317         changelog_clear 0 || error "changelog_clear failed"
14318         if [ x$flags != "x0x0" ]; then
14319                 error "flag $flags is not 0x0"
14320         fi
14321         echo "rename overwrite a target having nlink > 1," \
14322                 "changelog record has flags of $flags"
14323
14324         # rename doesn't overwrite a target (changelog flag 0x0)
14325         touch $DIR/$tdir/foo_161c
14326         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
14327         changelog_dump | grep RENME | tail -n 5
14328         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
14329         changelog_clear 0 || error "changelog_clear failed"
14330         if [ x$flags != "x0x0" ]; then
14331                 error "flag $flags is not 0x0"
14332         fi
14333         echo "rename doesn't overwrite a target," \
14334                 "changelog record has flags of $flags"
14335
14336         # define CLF_UNLINK_LAST 0x0001
14337         # unlink a file having nlink = 1 (changelog flag 0x1)
14338         rm -f $DIR/$tdir/foo2_161c
14339         changelog_dump | grep UNLNK | tail -n 5
14340         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14341         changelog_clear 0 || error "changelog_clear failed"
14342         if [ x$flags != "x0x1" ]; then
14343                 error "flag $flags is not 0x1"
14344         fi
14345         echo "unlink a file having nlink = 1," \
14346                 "changelog record has flags of $flags"
14347
14348         # unlink a file having nlink > 1 (changelog flag 0x0)
14349         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14350         rm -f $DIR/$tdir/foobar_161c
14351         changelog_dump | grep UNLNK | tail -n 5
14352         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14353         changelog_clear 0 || error "changelog_clear failed"
14354         if [ x$flags != "x0x0" ]; then
14355                 error "flag $flags is not 0x0"
14356         fi
14357         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
14358 }
14359 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
14360
14361 test_161d() {
14362         remote_mds_nodsh && skip "remote MDS with nodsh"
14363         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
14364
14365         local pid
14366         local fid
14367
14368         changelog_register || error "changelog_register failed"
14369
14370         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
14371         # interfer with $MOUNT/.lustre/fid/ access
14372         mkdir $DIR/$tdir
14373         [[ $? -eq 0 ]] || error "mkdir failed"
14374
14375         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
14376         $LCTL set_param fail_loc=0x8000140c
14377         # 5s pause
14378         $LCTL set_param fail_val=5
14379
14380         # create file
14381         echo foofoo > $DIR/$tdir/$tfile &
14382         pid=$!
14383
14384         # wait for create to be delayed
14385         sleep 2
14386
14387         ps -p $pid
14388         [[ $? -eq 0 ]] || error "create should be blocked"
14389
14390         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
14391         stack_trap "rm -f $tempfile"
14392         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
14393         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
14394         # some delay may occur during ChangeLog publishing and file read just
14395         # above, that could allow file write to happen finally
14396         [[ -s $tempfile ]] && echo "file should be empty"
14397
14398         $LCTL set_param fail_loc=0
14399
14400         wait $pid
14401         [[ $? -eq 0 ]] || error "create failed"
14402 }
14403 run_test 161d "create with concurrent .lustre/fid access"
14404
14405 check_path() {
14406         local expected="$1"
14407         shift
14408         local fid="$2"
14409
14410         local path
14411         path=$($LFS fid2path "$@")
14412         local rc=$?
14413
14414         if [ $rc -ne 0 ]; then
14415                 error "path looked up of '$expected' failed: rc=$rc"
14416         elif [ "$path" != "$expected" ]; then
14417                 error "path looked up '$path' instead of '$expected'"
14418         else
14419                 echo "FID '$fid' resolves to path '$path' as expected"
14420         fi
14421 }
14422
14423 test_162a() { # was test_162
14424         test_mkdir -p -c1 $DIR/$tdir/d2
14425         touch $DIR/$tdir/d2/$tfile
14426         touch $DIR/$tdir/d2/x1
14427         touch $DIR/$tdir/d2/x2
14428         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
14429         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
14430         # regular file
14431         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
14432         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
14433
14434         # softlink
14435         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
14436         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
14437         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
14438
14439         # softlink to wrong file
14440         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
14441         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
14442         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
14443
14444         # hardlink
14445         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
14446         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
14447         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
14448         # fid2path dir/fsname should both work
14449         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
14450         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
14451
14452         # hardlink count: check that there are 2 links
14453         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
14454         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
14455
14456         # hardlink indexing: remove the first link
14457         rm $DIR/$tdir/d2/p/q/r/hlink
14458         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
14459 }
14460 run_test 162a "path lookup sanity"
14461
14462 test_162b() {
14463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14464         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14465
14466         mkdir $DIR/$tdir
14467         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
14468                                 error "create striped dir failed"
14469
14470         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
14471                                         tail -n 1 | awk '{print $2}')
14472         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
14473
14474         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
14475         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
14476
14477         # regular file
14478         for ((i=0;i<5;i++)); do
14479                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
14480                         error "get fid for f$i failed"
14481                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
14482
14483                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
14484                         error "get fid for d$i failed"
14485                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
14486         done
14487
14488         return 0
14489 }
14490 run_test 162b "striped directory path lookup sanity"
14491
14492 # LU-4239: Verify fid2path works with paths 100 or more directories deep
14493 test_162c() {
14494         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
14495                 skip "Need MDS version at least 2.7.51"
14496
14497         local lpath=$tdir.local
14498         local rpath=$tdir.remote
14499
14500         test_mkdir $DIR/$lpath
14501         test_mkdir $DIR/$rpath
14502
14503         for ((i = 0; i <= 101; i++)); do
14504                 lpath="$lpath/$i"
14505                 mkdir $DIR/$lpath
14506                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
14507                         error "get fid for local directory $DIR/$lpath failed"
14508                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
14509
14510                 rpath="$rpath/$i"
14511                 test_mkdir $DIR/$rpath
14512                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
14513                         error "get fid for remote directory $DIR/$rpath failed"
14514                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
14515         done
14516
14517         return 0
14518 }
14519 run_test 162c "fid2path works with paths 100 or more directories deep"
14520
14521 test_169() {
14522         # do directio so as not to populate the page cache
14523         log "creating a 10 Mb file"
14524         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14525         log "starting reads"
14526         dd if=$DIR/$tfile of=/dev/null bs=4096 &
14527         log "truncating the file"
14528         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14529         log "killing dd"
14530         kill %+ || true # reads might have finished
14531         echo "wait until dd is finished"
14532         wait
14533         log "removing the temporary file"
14534         rm -rf $DIR/$tfile || error "tmp file removal failed"
14535 }
14536 run_test 169 "parallel read and truncate should not deadlock"
14537
14538 test_170() {
14539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14540
14541         $LCTL clear     # bug 18514
14542         $LCTL debug_daemon start $TMP/${tfile}_log_good
14543         touch $DIR/$tfile
14544         $LCTL debug_daemon stop
14545         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
14546                 error "sed failed to read log_good"
14547
14548         $LCTL debug_daemon start $TMP/${tfile}_log_good
14549         rm -rf $DIR/$tfile
14550         $LCTL debug_daemon stop
14551
14552         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
14553                error "lctl df log_bad failed"
14554
14555         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14556         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14557
14558         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
14559         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
14560
14561         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
14562                 error "bad_line good_line1 good_line2 are empty"
14563
14564         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14565         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14566         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14567
14568         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14569         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14570         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14571
14572         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14573                 error "bad_line_new good_line_new are empty"
14574
14575         local expected_good=$((good_line1 + good_line2*2))
14576
14577         rm -f $TMP/${tfile}*
14578         # LU-231, short malformed line may not be counted into bad lines
14579         if [ $bad_line -ne $bad_line_new ] &&
14580                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14581                 error "expected $bad_line bad lines, but got $bad_line_new"
14582                 return 1
14583         fi
14584
14585         if [ $expected_good -ne $good_line_new ]; then
14586                 error "expected $expected_good good lines, but got $good_line_new"
14587                 return 2
14588         fi
14589         true
14590 }
14591 run_test 170 "test lctl df to handle corrupted log ====================="
14592
14593 test_171() { # bug20592
14594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14595
14596         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
14597         $LCTL set_param fail_loc=0x50e
14598         $LCTL set_param fail_val=3000
14599         multiop_bg_pause $DIR/$tfile O_s || true
14600         local MULTIPID=$!
14601         kill -USR1 $MULTIPID
14602         # cause log dump
14603         sleep 3
14604         wait $MULTIPID
14605         if dmesg | grep "recursive fault"; then
14606                 error "caught a recursive fault"
14607         fi
14608         $LCTL set_param fail_loc=0
14609         true
14610 }
14611 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
14612
14613 # it would be good to share it with obdfilter-survey/iokit-libecho code
14614 setup_obdecho_osc () {
14615         local rc=0
14616         local ost_nid=$1
14617         local obdfilter_name=$2
14618         echo "Creating new osc for $obdfilter_name on $ost_nid"
14619         # make sure we can find loopback nid
14620         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
14621
14622         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
14623                            ${obdfilter_name}_osc_UUID || rc=2; }
14624         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
14625                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
14626         return $rc
14627 }
14628
14629 cleanup_obdecho_osc () {
14630         local obdfilter_name=$1
14631         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14632         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14633         return 0
14634 }
14635
14636 obdecho_test() {
14637         local OBD=$1
14638         local node=$2
14639         local pages=${3:-64}
14640         local rc=0
14641         local id
14642
14643         local count=10
14644         local obd_size=$(get_obd_size $node $OBD)
14645         local page_size=$(get_page_size $node)
14646         if [[ -n "$obd_size" ]]; then
14647                 local new_count=$((obd_size / (pages * page_size / 1024)))
14648                 [[ $new_count -ge $count ]] || count=$new_count
14649         fi
14650
14651         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14652         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14653                            rc=2; }
14654         if [ $rc -eq 0 ]; then
14655             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14656             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14657         fi
14658         echo "New object id is $id"
14659         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14660                            rc=4; }
14661         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14662                            "test_brw $count w v $pages $id" || rc=4; }
14663         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14664                            rc=4; }
14665         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14666                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14667         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14668                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14669         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14670         return $rc
14671 }
14672
14673 test_180a() {
14674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14675
14676         if ! module_loaded obdecho; then
14677                 load_module obdecho/obdecho &&
14678                         stack_trap "rmmod obdecho" EXIT ||
14679                         error "unable to load obdecho on client"
14680         fi
14681
14682         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14683         local host=$($LCTL get_param -n osc.$osc.import |
14684                      awk '/current_connection:/ { print $2 }' )
14685         local target=$($LCTL get_param -n osc.$osc.import |
14686                        awk '/target:/ { print $2 }' )
14687         target=${target%_UUID}
14688
14689         if [ -n "$target" ]; then
14690                 setup_obdecho_osc $host $target &&
14691                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14692                         { error "obdecho setup failed with $?"; return; }
14693
14694                 obdecho_test ${target}_osc client ||
14695                         error "obdecho_test failed on ${target}_osc"
14696         else
14697                 $LCTL get_param osc.$osc.import
14698                 error "there is no osc.$osc.import target"
14699         fi
14700 }
14701 run_test 180a "test obdecho on osc"
14702
14703 test_180b() {
14704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14705         remote_ost_nodsh && skip "remote OST with nodsh"
14706
14707         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14708                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14709                 error "failed to load module obdecho"
14710
14711         local target=$(do_facet ost1 $LCTL dl |
14712                        awk '/obdfilter/ { print $4; exit; }')
14713
14714         if [ -n "$target" ]; then
14715                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14716         else
14717                 do_facet ost1 $LCTL dl
14718                 error "there is no obdfilter target on ost1"
14719         fi
14720 }
14721 run_test 180b "test obdecho directly on obdfilter"
14722
14723 test_180c() { # LU-2598
14724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14725         remote_ost_nodsh && skip "remote OST with nodsh"
14726         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14727                 skip "Need MDS version at least 2.4.0"
14728
14729         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14730                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14731                 error "failed to load module obdecho"
14732
14733         local target=$(do_facet ost1 $LCTL dl |
14734                        awk '/obdfilter/ { print $4; exit; }')
14735
14736         if [ -n "$target" ]; then
14737                 local pages=16384 # 64MB bulk I/O RPC size
14738
14739                 obdecho_test "$target" ost1 "$pages" ||
14740                         error "obdecho_test with pages=$pages failed with $?"
14741         else
14742                 do_facet ost1 $LCTL dl
14743                 error "there is no obdfilter target on ost1"
14744         fi
14745 }
14746 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14747
14748 test_181() { # bug 22177
14749         test_mkdir $DIR/$tdir
14750         # create enough files to index the directory
14751         createmany -o $DIR/$tdir/foobar 4000
14752         # print attributes for debug purpose
14753         lsattr -d .
14754         # open dir
14755         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14756         MULTIPID=$!
14757         # remove the files & current working dir
14758         unlinkmany $DIR/$tdir/foobar 4000
14759         rmdir $DIR/$tdir
14760         kill -USR1 $MULTIPID
14761         wait $MULTIPID
14762         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14763         return 0
14764 }
14765 run_test 181 "Test open-unlinked dir ========================"
14766
14767 test_182() {
14768         local fcount=1000
14769         local tcount=10
14770
14771         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14772
14773         $LCTL set_param mdc.*.rpc_stats=clear
14774
14775         for (( i = 0; i < $tcount; i++ )) ; do
14776                 mkdir $DIR/$tdir/$i
14777         done
14778
14779         for (( i = 0; i < $tcount; i++ )) ; do
14780                 createmany -o $DIR/$tdir/$i/f- $fcount &
14781         done
14782         wait
14783
14784         for (( i = 0; i < $tcount; i++ )) ; do
14785                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14786         done
14787         wait
14788
14789         $LCTL get_param mdc.*.rpc_stats
14790
14791         rm -rf $DIR/$tdir
14792 }
14793 run_test 182 "Test parallel modify metadata operations ================"
14794
14795 test_183() { # LU-2275
14796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14797         remote_mds_nodsh && skip "remote MDS with nodsh"
14798         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14799                 skip "Need MDS version at least 2.3.56"
14800
14801         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14802         echo aaa > $DIR/$tdir/$tfile
14803
14804 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14805         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14806
14807         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14808         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14809
14810         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14811
14812         # Flush negative dentry cache
14813         touch $DIR/$tdir/$tfile
14814
14815         # We are not checking for any leaked references here, they'll
14816         # become evident next time we do cleanup with module unload.
14817         rm -rf $DIR/$tdir
14818 }
14819 run_test 183 "No crash or request leak in case of strange dispositions ========"
14820
14821 # test suite 184 is for LU-2016, LU-2017
14822 test_184a() {
14823         check_swap_layouts_support
14824
14825         dir0=$DIR/$tdir/$testnum
14826         test_mkdir -p -c1 $dir0
14827         ref1=/etc/passwd
14828         ref2=/etc/group
14829         file1=$dir0/f1
14830         file2=$dir0/f2
14831         $LFS setstripe -c1 $file1
14832         cp $ref1 $file1
14833         $LFS setstripe -c2 $file2
14834         cp $ref2 $file2
14835         gen1=$($LFS getstripe -g $file1)
14836         gen2=$($LFS getstripe -g $file2)
14837
14838         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14839         gen=$($LFS getstripe -g $file1)
14840         [[ $gen1 != $gen ]] ||
14841                 "Layout generation on $file1 does not change"
14842         gen=$($LFS getstripe -g $file2)
14843         [[ $gen2 != $gen ]] ||
14844                 "Layout generation on $file2 does not change"
14845
14846         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14847         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14848
14849         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14850 }
14851 run_test 184a "Basic layout swap"
14852
14853 test_184b() {
14854         check_swap_layouts_support
14855
14856         dir0=$DIR/$tdir/$testnum
14857         mkdir -p $dir0 || error "creating dir $dir0"
14858         file1=$dir0/f1
14859         file2=$dir0/f2
14860         file3=$dir0/f3
14861         dir1=$dir0/d1
14862         dir2=$dir0/d2
14863         mkdir $dir1 $dir2
14864         $LFS setstripe -c1 $file1
14865         $LFS setstripe -c2 $file2
14866         $LFS setstripe -c1 $file3
14867         chown $RUNAS_ID $file3
14868         gen1=$($LFS getstripe -g $file1)
14869         gen2=$($LFS getstripe -g $file2)
14870
14871         $LFS swap_layouts $dir1 $dir2 &&
14872                 error "swap of directories layouts should fail"
14873         $LFS swap_layouts $dir1 $file1 &&
14874                 error "swap of directory and file layouts should fail"
14875         $RUNAS $LFS swap_layouts $file1 $file2 &&
14876                 error "swap of file we cannot write should fail"
14877         $LFS swap_layouts $file1 $file3 &&
14878                 error "swap of file with different owner should fail"
14879         /bin/true # to clear error code
14880 }
14881 run_test 184b "Forbidden layout swap (will generate errors)"
14882
14883 test_184c() {
14884         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14885         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14886         check_swap_layouts_support
14887
14888         local dir0=$DIR/$tdir/$testnum
14889         mkdir -p $dir0 || error "creating dir $dir0"
14890
14891         local ref1=$dir0/ref1
14892         local ref2=$dir0/ref2
14893         local file1=$dir0/file1
14894         local file2=$dir0/file2
14895         # create a file large enough for the concurrent test
14896         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14897         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14898         echo "ref file size: ref1($(stat -c %s $ref1))," \
14899              "ref2($(stat -c %s $ref2))"
14900
14901         cp $ref2 $file2
14902         dd if=$ref1 of=$file1 bs=16k &
14903         local DD_PID=$!
14904
14905         # Make sure dd starts to copy file
14906         while [ ! -f $file1 ]; do sleep 0.1; done
14907
14908         $LFS swap_layouts $file1 $file2
14909         local rc=$?
14910         wait $DD_PID
14911         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14912         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14913
14914         # how many bytes copied before swapping layout
14915         local copied=$(stat -c %s $file2)
14916         local remaining=$(stat -c %s $ref1)
14917         remaining=$((remaining - copied))
14918         echo "Copied $copied bytes before swapping layout..."
14919
14920         cmp -n $copied $file1 $ref2 | grep differ &&
14921                 error "Content mismatch [0, $copied) of ref2 and file1"
14922         cmp -n $copied $file2 $ref1 ||
14923                 error "Content mismatch [0, $copied) of ref1 and file2"
14924         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14925                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14926
14927         # clean up
14928         rm -f $ref1 $ref2 $file1 $file2
14929 }
14930 run_test 184c "Concurrent write and layout swap"
14931
14932 test_184d() {
14933         check_swap_layouts_support
14934         [ -z "$(which getfattr 2>/dev/null)" ] &&
14935                 skip_env "no getfattr command"
14936
14937         local file1=$DIR/$tdir/$tfile-1
14938         local file2=$DIR/$tdir/$tfile-2
14939         local file3=$DIR/$tdir/$tfile-3
14940         local lovea1
14941         local lovea2
14942
14943         mkdir -p $DIR/$tdir
14944         touch $file1 || error "create $file1 failed"
14945         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14946                 error "create $file2 failed"
14947         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14948                 error "create $file3 failed"
14949         lovea1=$(get_layout_param $file1)
14950
14951         $LFS swap_layouts $file2 $file3 ||
14952                 error "swap $file2 $file3 layouts failed"
14953         $LFS swap_layouts $file1 $file2 ||
14954                 error "swap $file1 $file2 layouts failed"
14955
14956         lovea2=$(get_layout_param $file2)
14957         echo "$lovea1"
14958         echo "$lovea2"
14959         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14960
14961         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14962         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14963 }
14964 run_test 184d "allow stripeless layouts swap"
14965
14966 test_184e() {
14967         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14968                 skip "Need MDS version at least 2.6.94"
14969         check_swap_layouts_support
14970         [ -z "$(which getfattr 2>/dev/null)" ] &&
14971                 skip_env "no getfattr command"
14972
14973         local file1=$DIR/$tdir/$tfile-1
14974         local file2=$DIR/$tdir/$tfile-2
14975         local file3=$DIR/$tdir/$tfile-3
14976         local lovea
14977
14978         mkdir -p $DIR/$tdir
14979         touch $file1 || error "create $file1 failed"
14980         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14981                 error "create $file2 failed"
14982         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14983                 error "create $file3 failed"
14984
14985         $LFS swap_layouts $file1 $file2 ||
14986                 error "swap $file1 $file2 layouts failed"
14987
14988         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14989         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
14990
14991         echo 123 > $file1 || error "Should be able to write into $file1"
14992
14993         $LFS swap_layouts $file1 $file3 ||
14994                 error "swap $file1 $file3 layouts failed"
14995
14996         echo 123 > $file1 || error "Should be able to write into $file1"
14997
14998         rm -rf $file1 $file2 $file3
14999 }
15000 run_test 184e "Recreate layout after stripeless layout swaps"
15001
15002 test_184f() {
15003         # Create a file with name longer than sizeof(struct stat) ==
15004         # 144 to see if we can get chars from the file name to appear
15005         # in the returned striping. Note that 'f' == 0x66.
15006         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
15007
15008         mkdir -p $DIR/$tdir
15009         mcreate $DIR/$tdir/$file
15010         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
15011                 error "IOC_MDC_GETFILEINFO returned garbage striping"
15012         fi
15013 }
15014 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
15015
15016 test_185() { # LU-2441
15017         # LU-3553 - no volatile file support in old servers
15018         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
15019                 skip "Need MDS version at least 2.3.60"
15020
15021         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15022         touch $DIR/$tdir/spoo
15023         local mtime1=$(stat -c "%Y" $DIR/$tdir)
15024         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
15025                 error "cannot create/write a volatile file"
15026         [ "$FILESET" == "" ] &&
15027         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
15028                 error "FID is still valid after close"
15029
15030         multiop_bg_pause $DIR/$tdir vVw4096_c
15031         local multi_pid=$!
15032
15033         local OLD_IFS=$IFS
15034         IFS=":"
15035         local fidv=($fid)
15036         IFS=$OLD_IFS
15037         # assume that the next FID for this client is sequential, since stdout
15038         # is unfortunately eaten by multiop_bg_pause
15039         local n=$((${fidv[1]} + 1))
15040         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
15041         if [ "$FILESET" == "" ]; then
15042                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
15043                         error "FID is missing before close"
15044         fi
15045         kill -USR1 $multi_pid
15046         # 1 second delay, so if mtime change we will see it
15047         sleep 1
15048         local mtime2=$(stat -c "%Y" $DIR/$tdir)
15049         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
15050 }
15051 run_test 185 "Volatile file support"
15052
15053 function create_check_volatile() {
15054         local idx=$1
15055         local tgt
15056
15057         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
15058         local PID=$!
15059         sleep 1
15060         local FID=$(cat /tmp/${tfile}.fid)
15061         [ "$FID" == "" ] && error "can't get FID for volatile"
15062         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
15063         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
15064         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
15065         kill -USR1 $PID
15066         wait
15067         sleep 1
15068         cancel_lru_locks mdc # flush opencache
15069         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
15070         return 0
15071 }
15072
15073 test_185a(){
15074         # LU-12516 - volatile creation via .lustre
15075         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
15076                 skip "Need MDS version at least 2.3.55"
15077
15078         create_check_volatile 0
15079         [ $MDSCOUNT -lt 2 ] && return 0
15080
15081         # DNE case
15082         create_check_volatile 1
15083
15084         return 0
15085 }
15086 run_test 185a "Volatile file creation in .lustre/fid/"
15087
15088 test_187a() {
15089         remote_mds_nodsh && skip "remote MDS with nodsh"
15090         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15091                 skip "Need MDS version at least 2.3.0"
15092
15093         local dir0=$DIR/$tdir/$testnum
15094         mkdir -p $dir0 || error "creating dir $dir0"
15095
15096         local file=$dir0/file1
15097         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
15098         local dv1=$($LFS data_version $file)
15099         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
15100         local dv2=$($LFS data_version $file)
15101         [[ $dv1 != $dv2 ]] ||
15102                 error "data version did not change on write $dv1 == $dv2"
15103
15104         # clean up
15105         rm -f $file1
15106 }
15107 run_test 187a "Test data version change"
15108
15109 test_187b() {
15110         remote_mds_nodsh && skip "remote MDS with nodsh"
15111         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15112                 skip "Need MDS version at least 2.3.0"
15113
15114         local dir0=$DIR/$tdir/$testnum
15115         mkdir -p $dir0 || error "creating dir $dir0"
15116
15117         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
15118         [[ ${DV[0]} != ${DV[1]} ]] ||
15119                 error "data version did not change on write"\
15120                       " ${DV[0]} == ${DV[1]}"
15121
15122         # clean up
15123         rm -f $file1
15124 }
15125 run_test 187b "Test data version change on volatile file"
15126
15127 test_200() {
15128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15129         remote_mgs_nodsh && skip "remote MGS with nodsh"
15130         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15131
15132         local POOL=${POOL:-cea1}
15133         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
15134         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
15135         # Pool OST targets
15136         local first_ost=0
15137         local last_ost=$(($OSTCOUNT - 1))
15138         local ost_step=2
15139         local ost_list=$(seq $first_ost $ost_step $last_ost)
15140         local ost_range="$first_ost $last_ost $ost_step"
15141         local test_path=$POOL_ROOT/$POOL_DIR_NAME
15142         local file_dir=$POOL_ROOT/file_tst
15143         local subdir=$test_path/subdir
15144         local rc=0
15145
15146         while : ; do
15147                 # former test_200a test_200b
15148                 pool_add $POOL                          || { rc=$? ; break; }
15149                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
15150                 # former test_200c test_200d
15151                 mkdir -p $test_path
15152                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
15153                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
15154                 mkdir -p $subdir
15155                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
15156                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
15157                                                         || { rc=$? ; break; }
15158                 # former test_200e test_200f
15159                 local files=$((OSTCOUNT*3))
15160                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
15161                                                         || { rc=$? ; break; }
15162                 pool_create_files $POOL $file_dir $files "$ost_list" \
15163                                                         || { rc=$? ; break; }
15164                 # former test_200g test_200h
15165                 pool_lfs_df $POOL                       || { rc=$? ; break; }
15166                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
15167
15168                 # former test_201a test_201b test_201c
15169                 pool_remove_first_target $POOL          || { rc=$? ; break; }
15170
15171                 local f=$test_path/$tfile
15172                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
15173                 pool_remove $POOL $f                    || { rc=$? ; break; }
15174                 break
15175         done
15176
15177         destroy_test_pools
15178
15179         return $rc
15180 }
15181 run_test 200 "OST pools"
15182
15183 # usage: default_attr <count | size | offset>
15184 default_attr() {
15185         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
15186 }
15187
15188 # usage: check_default_stripe_attr
15189 check_default_stripe_attr() {
15190         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
15191         case $1 in
15192         --stripe-count|-c)
15193                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
15194         --stripe-size|-S)
15195                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
15196         --stripe-index|-i)
15197                 EXPECTED=-1;;
15198         *)
15199                 error "unknown getstripe attr '$1'"
15200         esac
15201
15202         [ $ACTUAL == $EXPECTED ] ||
15203                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
15204 }
15205
15206 test_204a() {
15207         test_mkdir $DIR/$tdir
15208         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
15209
15210         check_default_stripe_attr --stripe-count
15211         check_default_stripe_attr --stripe-size
15212         check_default_stripe_attr --stripe-index
15213 }
15214 run_test 204a "Print default stripe attributes"
15215
15216 test_204b() {
15217         test_mkdir $DIR/$tdir
15218         $LFS setstripe --stripe-count 1 $DIR/$tdir
15219
15220         check_default_stripe_attr --stripe-size
15221         check_default_stripe_attr --stripe-index
15222 }
15223 run_test 204b "Print default stripe size and offset"
15224
15225 test_204c() {
15226         test_mkdir $DIR/$tdir
15227         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15228
15229         check_default_stripe_attr --stripe-count
15230         check_default_stripe_attr --stripe-index
15231 }
15232 run_test 204c "Print default stripe count and offset"
15233
15234 test_204d() {
15235         test_mkdir $DIR/$tdir
15236         $LFS setstripe --stripe-index 0 $DIR/$tdir
15237
15238         check_default_stripe_attr --stripe-count
15239         check_default_stripe_attr --stripe-size
15240 }
15241 run_test 204d "Print default stripe count and size"
15242
15243 test_204e() {
15244         test_mkdir $DIR/$tdir
15245         $LFS setstripe -d $DIR/$tdir
15246
15247         check_default_stripe_attr --stripe-count --raw
15248         check_default_stripe_attr --stripe-size --raw
15249         check_default_stripe_attr --stripe-index --raw
15250 }
15251 run_test 204e "Print raw stripe attributes"
15252
15253 test_204f() {
15254         test_mkdir $DIR/$tdir
15255         $LFS setstripe --stripe-count 1 $DIR/$tdir
15256
15257         check_default_stripe_attr --stripe-size --raw
15258         check_default_stripe_attr --stripe-index --raw
15259 }
15260 run_test 204f "Print raw stripe size and offset"
15261
15262 test_204g() {
15263         test_mkdir $DIR/$tdir
15264         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15265
15266         check_default_stripe_attr --stripe-count --raw
15267         check_default_stripe_attr --stripe-index --raw
15268 }
15269 run_test 204g "Print raw stripe count and offset"
15270
15271 test_204h() {
15272         test_mkdir $DIR/$tdir
15273         $LFS setstripe --stripe-index 0 $DIR/$tdir
15274
15275         check_default_stripe_attr --stripe-count --raw
15276         check_default_stripe_attr --stripe-size --raw
15277 }
15278 run_test 204h "Print raw stripe count and size"
15279
15280 # Figure out which job scheduler is being used, if any,
15281 # or use a fake one
15282 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
15283         JOBENV=SLURM_JOB_ID
15284 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
15285         JOBENV=LSB_JOBID
15286 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
15287         JOBENV=PBS_JOBID
15288 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
15289         JOBENV=LOADL_STEP_ID
15290 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
15291         JOBENV=JOB_ID
15292 else
15293         $LCTL list_param jobid_name > /dev/null 2>&1
15294         if [ $? -eq 0 ]; then
15295                 JOBENV=nodelocal
15296         else
15297                 JOBENV=FAKE_JOBID
15298         fi
15299 fi
15300 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
15301
15302 verify_jobstats() {
15303         local cmd=($1)
15304         shift
15305         local facets="$@"
15306
15307 # we don't really need to clear the stats for this test to work, since each
15308 # command has a unique jobid, but it makes debugging easier if needed.
15309 #       for facet in $facets; do
15310 #               local dev=$(convert_facet2label $facet)
15311 #               # clear old jobstats
15312 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
15313 #       done
15314
15315         # use a new JobID for each test, or we might see an old one
15316         [ "$JOBENV" = "FAKE_JOBID" ] &&
15317                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
15318
15319         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
15320
15321         [ "$JOBENV" = "nodelocal" ] && {
15322                 FAKE_JOBID=id.$testnum.%e.$RANDOM
15323                 $LCTL set_param jobid_name=$FAKE_JOBID
15324                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
15325         }
15326
15327         log "Test: ${cmd[*]}"
15328         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
15329
15330         if [ $JOBENV = "FAKE_JOBID" ]; then
15331                 FAKE_JOBID=$JOBVAL ${cmd[*]}
15332         else
15333                 ${cmd[*]}
15334         fi
15335
15336         # all files are created on OST0000
15337         for facet in $facets; do
15338                 local stats="*.$(convert_facet2label $facet).job_stats"
15339
15340                 # strip out libtool wrappers for in-tree executables
15341                 if [ $(do_facet $facet lctl get_param $stats |
15342                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
15343                         do_facet $facet lctl get_param $stats
15344                         error "No jobstats for $JOBVAL found on $facet::$stats"
15345                 fi
15346         done
15347 }
15348
15349 jobstats_set() {
15350         local new_jobenv=$1
15351
15352         set_persistent_param_and_check client "jobid_var" \
15353                 "$FSNAME.sys.jobid_var" $new_jobenv
15354 }
15355
15356 test_205() { # Job stats
15357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15358         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
15359                 skip "Need MDS version with at least 2.7.1"
15360         remote_mgs_nodsh && skip "remote MGS with nodsh"
15361         remote_mds_nodsh && skip "remote MDS with nodsh"
15362         remote_ost_nodsh && skip "remote OST with nodsh"
15363         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
15364                 skip "Server doesn't support jobstats"
15365         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
15366
15367         local old_jobenv=$($LCTL get_param -n jobid_var)
15368         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
15369
15370         if [[ $PERM_CMD == *"set_param -P"* ]]; then
15371                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
15372         else
15373                 stack_trap "do_facet mgs $PERM_CMD \
15374                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
15375         fi
15376         changelog_register
15377
15378         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
15379                                 mdt.*.job_cleanup_interval | head -n 1)
15380         local new_interval=5
15381         do_facet $SINGLEMDS \
15382                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
15383         stack_trap "do_facet $SINGLEMDS \
15384                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
15385         local start=$SECONDS
15386
15387         local cmd
15388         # mkdir
15389         cmd="mkdir $DIR/$tdir"
15390         verify_jobstats "$cmd" "$SINGLEMDS"
15391         # rmdir
15392         cmd="rmdir $DIR/$tdir"
15393         verify_jobstats "$cmd" "$SINGLEMDS"
15394         # mkdir on secondary MDT
15395         if [ $MDSCOUNT -gt 1 ]; then
15396                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
15397                 verify_jobstats "$cmd" "mds2"
15398         fi
15399         # mknod
15400         cmd="mknod $DIR/$tfile c 1 3"
15401         verify_jobstats "$cmd" "$SINGLEMDS"
15402         # unlink
15403         cmd="rm -f $DIR/$tfile"
15404         verify_jobstats "$cmd" "$SINGLEMDS"
15405         # create all files on OST0000 so verify_jobstats can find OST stats
15406         # open & close
15407         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
15408         verify_jobstats "$cmd" "$SINGLEMDS"
15409         # setattr
15410         cmd="touch $DIR/$tfile"
15411         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15412         # write
15413         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
15414         verify_jobstats "$cmd" "ost1"
15415         # read
15416         cancel_lru_locks osc
15417         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
15418         verify_jobstats "$cmd" "ost1"
15419         # truncate
15420         cmd="$TRUNCATE $DIR/$tfile 0"
15421         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15422         # rename
15423         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
15424         verify_jobstats "$cmd" "$SINGLEMDS"
15425         # jobstats expiry - sleep until old stats should be expired
15426         local left=$((new_interval + 5 - (SECONDS - start)))
15427         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
15428                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
15429                         "0" $left
15430         cmd="mkdir $DIR/$tdir.expire"
15431         verify_jobstats "$cmd" "$SINGLEMDS"
15432         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
15433             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
15434
15435         # Ensure that jobid are present in changelog (if supported by MDS)
15436         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
15437                 changelog_dump | tail -10
15438                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
15439                 [ $jobids -eq 9 ] ||
15440                         error "Wrong changelog jobid count $jobids != 9"
15441
15442                 # LU-5862
15443                 JOBENV="disable"
15444                 jobstats_set $JOBENV
15445                 touch $DIR/$tfile
15446                 changelog_dump | grep $tfile
15447                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
15448                 [ $jobids -eq 0 ] ||
15449                         error "Unexpected jobids when jobid_var=$JOBENV"
15450         fi
15451
15452         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
15453         JOBENV="JOBCOMPLEX"
15454         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
15455
15456         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
15457 }
15458 run_test 205 "Verify job stats"
15459
15460 # LU-1480, LU-1773 and LU-1657
15461 test_206() {
15462         mkdir -p $DIR/$tdir
15463         $LFS setstripe -c -1 $DIR/$tdir
15464 #define OBD_FAIL_LOV_INIT 0x1403
15465         $LCTL set_param fail_loc=0xa0001403
15466         $LCTL set_param fail_val=1
15467         touch $DIR/$tdir/$tfile || true
15468 }
15469 run_test 206 "fail lov_init_raid0() doesn't lbug"
15470
15471 test_207a() {
15472         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15473         local fsz=`stat -c %s $DIR/$tfile`
15474         cancel_lru_locks mdc
15475
15476         # do not return layout in getattr intent
15477 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
15478         $LCTL set_param fail_loc=0x170
15479         local sz=`stat -c %s $DIR/$tfile`
15480
15481         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
15482
15483         rm -rf $DIR/$tfile
15484 }
15485 run_test 207a "can refresh layout at glimpse"
15486
15487 test_207b() {
15488         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15489         local cksum=`md5sum $DIR/$tfile`
15490         local fsz=`stat -c %s $DIR/$tfile`
15491         cancel_lru_locks mdc
15492         cancel_lru_locks osc
15493
15494         # do not return layout in getattr intent
15495 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
15496         $LCTL set_param fail_loc=0x171
15497
15498         # it will refresh layout after the file is opened but before read issues
15499         echo checksum is "$cksum"
15500         echo "$cksum" |md5sum -c --quiet || error "file differs"
15501
15502         rm -rf $DIR/$tfile
15503 }
15504 run_test 207b "can refresh layout at open"
15505
15506 test_208() {
15507         # FIXME: in this test suite, only RD lease is used. This is okay
15508         # for now as only exclusive open is supported. After generic lease
15509         # is done, this test suite should be revised. - Jinshan
15510
15511         remote_mds_nodsh && skip "remote MDS with nodsh"
15512         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
15513                 skip "Need MDS version at least 2.4.52"
15514
15515         echo "==== test 1: verify get lease work"
15516         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
15517
15518         echo "==== test 2: verify lease can be broken by upcoming open"
15519         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15520         local PID=$!
15521         sleep 1
15522
15523         $MULTIOP $DIR/$tfile oO_RDONLY:c
15524         kill -USR1 $PID && wait $PID || error "break lease error"
15525
15526         echo "==== test 3: verify lease can't be granted if an open already exists"
15527         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
15528         local PID=$!
15529         sleep 1
15530
15531         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
15532         kill -USR1 $PID && wait $PID || error "open file error"
15533
15534         echo "==== test 4: lease can sustain over recovery"
15535         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
15536         PID=$!
15537         sleep 1
15538
15539         fail mds1
15540
15541         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
15542
15543         echo "==== test 5: lease broken can't be regained by replay"
15544         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15545         PID=$!
15546         sleep 1
15547
15548         # open file to break lease and then recovery
15549         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
15550         fail mds1
15551
15552         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
15553
15554         rm -f $DIR/$tfile
15555 }
15556 run_test 208 "Exclusive open"
15557
15558 test_209() {
15559         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15560                 skip_env "must have disp_stripe"
15561
15562         touch $DIR/$tfile
15563         sync; sleep 5; sync;
15564
15565         echo 3 > /proc/sys/vm/drop_caches
15566         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15567
15568         # open/close 500 times
15569         for i in $(seq 500); do
15570                 cat $DIR/$tfile
15571         done
15572
15573         echo 3 > /proc/sys/vm/drop_caches
15574         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15575
15576         echo "before: $req_before, after: $req_after"
15577         [ $((req_after - req_before)) -ge 300 ] &&
15578                 error "open/close requests are not freed"
15579         return 0
15580 }
15581 run_test 209 "read-only open/close requests should be freed promptly"
15582
15583 test_212() {
15584         size=`date +%s`
15585         size=$((size % 8192 + 1))
15586         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
15587         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
15588         rm -f $DIR/f212 $DIR/f212.xyz
15589 }
15590 run_test 212 "Sendfile test ============================================"
15591
15592 test_213() {
15593         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
15594         cancel_lru_locks osc
15595         lctl set_param fail_loc=0x8000040f
15596         # generate a read lock
15597         cat $DIR/$tfile > /dev/null
15598         # write to the file, it will try to cancel the above read lock.
15599         cat /etc/hosts >> $DIR/$tfile
15600 }
15601 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
15602
15603 test_214() { # for bug 20133
15604         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
15605         for (( i=0; i < 340; i++ )) ; do
15606                 touch $DIR/$tdir/d214c/a$i
15607         done
15608
15609         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
15610         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
15611         ls $DIR/d214c || error "ls $DIR/d214c failed"
15612         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
15613         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
15614 }
15615 run_test 214 "hash-indexed directory test - bug 20133"
15616
15617 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
15618 create_lnet_proc_files() {
15619         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
15620 }
15621
15622 # counterpart of create_lnet_proc_files
15623 remove_lnet_proc_files() {
15624         rm -f $TMP/lnet_$1.sys
15625 }
15626
15627 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15628 # 3rd arg as regexp for body
15629 check_lnet_proc_stats() {
15630         local l=$(cat "$TMP/lnet_$1" |wc -l)
15631         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
15632
15633         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
15634 }
15635
15636 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15637 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
15638 # optional and can be regexp for 2nd line (lnet.routes case)
15639 check_lnet_proc_entry() {
15640         local blp=2          # blp stands for 'position of 1st line of body'
15641         [ -z "$5" ] || blp=3 # lnet.routes case
15642
15643         local l=$(cat "$TMP/lnet_$1" |wc -l)
15644         # subtracting one from $blp because the body can be empty
15645         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
15646
15647         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
15648                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
15649
15650         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
15651                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
15652
15653         # bail out if any unexpected line happened
15654         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15655         [ "$?" != 0 ] || error "$2 misformatted"
15656 }
15657
15658 test_215() { # for bugs 18102, 21079, 21517
15659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15660
15661         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15662         local P='[1-9][0-9]*'           # positive numeric
15663         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15664         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15665         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15666         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15667
15668         local L1 # regexp for 1st line
15669         local L2 # regexp for 2nd line (optional)
15670         local BR # regexp for the rest (body)
15671
15672         # lnet.stats should look as 11 space-separated non-negative numerics
15673         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15674         create_lnet_proc_files "stats"
15675         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15676         remove_lnet_proc_files "stats"
15677
15678         # lnet.routes should look like this:
15679         # Routing disabled/enabled
15680         # net hops priority state router
15681         # where net is a string like tcp0, hops > 0, priority >= 0,
15682         # state is up/down,
15683         # router is a string like 192.168.1.1@tcp2
15684         L1="^Routing (disabled|enabled)$"
15685         L2="^net +hops +priority +state +router$"
15686         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15687         create_lnet_proc_files "routes"
15688         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15689         remove_lnet_proc_files "routes"
15690
15691         # lnet.routers should look like this:
15692         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15693         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15694         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15695         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15696         L1="^ref +rtr_ref +alive +router$"
15697         BR="^$P +$P +(up|down) +$NID$"
15698         create_lnet_proc_files "routers"
15699         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15700         remove_lnet_proc_files "routers"
15701
15702         # lnet.peers should look like this:
15703         # nid refs state last max rtr min tx min queue
15704         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15705         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15706         # numeric (0 or >0 or <0), queue >= 0.
15707         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15708         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15709         create_lnet_proc_files "peers"
15710         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15711         remove_lnet_proc_files "peers"
15712
15713         # lnet.buffers  should look like this:
15714         # pages count credits min
15715         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15716         L1="^pages +count +credits +min$"
15717         BR="^ +$N +$N +$I +$I$"
15718         create_lnet_proc_files "buffers"
15719         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15720         remove_lnet_proc_files "buffers"
15721
15722         # lnet.nis should look like this:
15723         # nid status alive refs peer rtr max tx min
15724         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15725         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15726         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15727         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15728         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15729         create_lnet_proc_files "nis"
15730         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15731         remove_lnet_proc_files "nis"
15732
15733         # can we successfully write to lnet.stats?
15734         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15735 }
15736 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15737
15738 test_216() { # bug 20317
15739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15740         remote_ost_nodsh && skip "remote OST with nodsh"
15741
15742         local node
15743         local facets=$(get_facets OST)
15744         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15745
15746         save_lustre_params client "osc.*.contention_seconds" > $p
15747         save_lustre_params $facets \
15748                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15749         save_lustre_params $facets \
15750                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15751         save_lustre_params $facets \
15752                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15753         clear_stats osc.*.osc_stats
15754
15755         # agressive lockless i/o settings
15756         do_nodes $(comma_list $(osts_nodes)) \
15757                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15758                         ldlm.namespaces.filter-*.contended_locks=0 \
15759                         ldlm.namespaces.filter-*.contention_seconds=60"
15760         lctl set_param -n osc.*.contention_seconds=60
15761
15762         $DIRECTIO write $DIR/$tfile 0 10 4096
15763         $CHECKSTAT -s 40960 $DIR/$tfile
15764
15765         # disable lockless i/o
15766         do_nodes $(comma_list $(osts_nodes)) \
15767                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15768                         ldlm.namespaces.filter-*.contended_locks=32 \
15769                         ldlm.namespaces.filter-*.contention_seconds=0"
15770         lctl set_param -n osc.*.contention_seconds=0
15771         clear_stats osc.*.osc_stats
15772
15773         dd if=/dev/zero of=$DIR/$tfile count=0
15774         $CHECKSTAT -s 0 $DIR/$tfile
15775
15776         restore_lustre_params <$p
15777         rm -f $p
15778         rm $DIR/$tfile
15779 }
15780 run_test 216 "check lockless direct write updates file size and kms correctly"
15781
15782 test_217() { # bug 22430
15783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15784
15785         local node
15786         local nid
15787
15788         for node in $(nodes_list); do
15789                 nid=$(host_nids_address $node $NETTYPE)
15790                 if [[ $nid = *-* ]] ; then
15791                         echo "lctl ping $(h2nettype $nid)"
15792                         lctl ping $(h2nettype $nid)
15793                 else
15794                         echo "skipping $node (no hyphen detected)"
15795                 fi
15796         done
15797 }
15798 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15799
15800 test_218() {
15801        # do directio so as not to populate the page cache
15802        log "creating a 10 Mb file"
15803        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15804        log "starting reads"
15805        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15806        log "truncating the file"
15807        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15808        log "killing dd"
15809        kill %+ || true # reads might have finished
15810        echo "wait until dd is finished"
15811        wait
15812        log "removing the temporary file"
15813        rm -rf $DIR/$tfile || error "tmp file removal failed"
15814 }
15815 run_test 218 "parallel read and truncate should not deadlock"
15816
15817 test_219() {
15818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15819
15820         # write one partial page
15821         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15822         # set no grant so vvp_io_commit_write will do sync write
15823         $LCTL set_param fail_loc=0x411
15824         # write a full page at the end of file
15825         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15826
15827         $LCTL set_param fail_loc=0
15828         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15829         $LCTL set_param fail_loc=0x411
15830         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15831
15832         # LU-4201
15833         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15834         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15835 }
15836 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15837
15838 test_220() { #LU-325
15839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15840         remote_ost_nodsh && skip "remote OST with nodsh"
15841         remote_mds_nodsh && skip "remote MDS with nodsh"
15842         remote_mgs_nodsh && skip "remote MGS with nodsh"
15843
15844         local OSTIDX=0
15845
15846         # create on MDT0000 so the last_id and next_id are correct
15847         mkdir $DIR/$tdir
15848         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15849         OST=${OST%_UUID}
15850
15851         # on the mdt's osc
15852         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15853         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15854                         osp.$mdtosc_proc1.prealloc_last_id)
15855         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15856                         osp.$mdtosc_proc1.prealloc_next_id)
15857
15858         $LFS df -i
15859
15860         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15861         #define OBD_FAIL_OST_ENOINO              0x229
15862         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15863         create_pool $FSNAME.$TESTNAME || return 1
15864         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15865
15866         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15867
15868         MDSOBJS=$((last_id - next_id))
15869         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15870
15871         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15872         echo "OST still has $count kbytes free"
15873
15874         echo "create $MDSOBJS files @next_id..."
15875         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15876
15877         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15878                         osp.$mdtosc_proc1.prealloc_last_id)
15879         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15880                         osp.$mdtosc_proc1.prealloc_next_id)
15881
15882         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15883         $LFS df -i
15884
15885         echo "cleanup..."
15886
15887         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15888         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15889
15890         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15891                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15892         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15893                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15894         echo "unlink $MDSOBJS files @$next_id..."
15895         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15896 }
15897 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15898
15899 test_221() {
15900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15901
15902         dd if=`which date` of=$MOUNT/date oflag=sync
15903         chmod +x $MOUNT/date
15904
15905         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15906         $LCTL set_param fail_loc=0x80001401
15907
15908         $MOUNT/date > /dev/null
15909         rm -f $MOUNT/date
15910 }
15911 run_test 221 "make sure fault and truncate race to not cause OOM"
15912
15913 test_222a () {
15914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15915
15916         rm -rf $DIR/$tdir
15917         test_mkdir $DIR/$tdir
15918         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15919         createmany -o $DIR/$tdir/$tfile 10
15920         cancel_lru_locks mdc
15921         cancel_lru_locks osc
15922         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15923         $LCTL set_param fail_loc=0x31a
15924         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15925         $LCTL set_param fail_loc=0
15926         rm -r $DIR/$tdir
15927 }
15928 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15929
15930 test_222b () {
15931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15932
15933         rm -rf $DIR/$tdir
15934         test_mkdir $DIR/$tdir
15935         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15936         createmany -o $DIR/$tdir/$tfile 10
15937         cancel_lru_locks mdc
15938         cancel_lru_locks osc
15939         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15940         $LCTL set_param fail_loc=0x31a
15941         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15942         $LCTL set_param fail_loc=0
15943 }
15944 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15945
15946 test_223 () {
15947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15948
15949         rm -rf $DIR/$tdir
15950         test_mkdir $DIR/$tdir
15951         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15952         createmany -o $DIR/$tdir/$tfile 10
15953         cancel_lru_locks mdc
15954         cancel_lru_locks osc
15955         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15956         $LCTL set_param fail_loc=0x31b
15957         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15958         $LCTL set_param fail_loc=0
15959         rm -r $DIR/$tdir
15960 }
15961 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15962
15963 test_224a() { # LU-1039, MRP-303
15964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15965
15966         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15967         $LCTL set_param fail_loc=0x508
15968         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15969         $LCTL set_param fail_loc=0
15970         df $DIR
15971 }
15972 run_test 224a "Don't panic on bulk IO failure"
15973
15974 test_224b() { # LU-1039, MRP-303
15975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15976
15977         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
15978         cancel_lru_locks osc
15979         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
15980         $LCTL set_param fail_loc=0x515
15981         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
15982         $LCTL set_param fail_loc=0
15983         df $DIR
15984 }
15985 run_test 224b "Don't panic on bulk IO failure"
15986
15987 test_224c() { # LU-6441
15988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15989         remote_mds_nodsh && skip "remote MDS with nodsh"
15990
15991         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15992         save_writethrough $p
15993         set_cache writethrough on
15994
15995         local pages_per_rpc=$($LCTL get_param \
15996                                 osc.*.max_pages_per_rpc)
15997         local at_max=$($LCTL get_param -n at_max)
15998         local timeout=$($LCTL get_param -n timeout)
15999         local test_at="at_max"
16000         local param_at="$FSNAME.sys.at_max"
16001         local test_timeout="timeout"
16002         local param_timeout="$FSNAME.sys.timeout"
16003
16004         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
16005
16006         set_persistent_param_and_check client "$test_at" "$param_at" 0
16007         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
16008
16009         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
16010         do_facet ost1 "$LCTL set_param fail_loc=0x520"
16011         $LFS setstripe -c 1 -i 0 $DIR/$tfile
16012         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
16013         sync
16014         do_facet ost1 "$LCTL set_param fail_loc=0"
16015
16016         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
16017         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
16018                 $timeout
16019
16020         $LCTL set_param -n $pages_per_rpc
16021         restore_lustre_params < $p
16022         rm -f $p
16023 }
16024 run_test 224c "Don't hang if one of md lost during large bulk RPC"
16025
16026 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
16027 test_225a () {
16028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16029         if [ -z ${MDSSURVEY} ]; then
16030                 skip_env "mds-survey not found"
16031         fi
16032         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16033                 skip "Need MDS version at least 2.2.51"
16034
16035         local mds=$(facet_host $SINGLEMDS)
16036         local target=$(do_nodes $mds 'lctl dl' |
16037                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16038
16039         local cmd1="file_count=1000 thrhi=4"
16040         local cmd2="dir_count=2 layer=mdd stripe_count=0"
16041         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16042         local cmd="$cmd1 $cmd2 $cmd3"
16043
16044         rm -f ${TMP}/mds_survey*
16045         echo + $cmd
16046         eval $cmd || error "mds-survey with zero-stripe failed"
16047         cat ${TMP}/mds_survey*
16048         rm -f ${TMP}/mds_survey*
16049 }
16050 run_test 225a "Metadata survey sanity with zero-stripe"
16051
16052 test_225b () {
16053         if [ -z ${MDSSURVEY} ]; then
16054                 skip_env "mds-survey not found"
16055         fi
16056         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16057                 skip "Need MDS version at least 2.2.51"
16058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16059         remote_mds_nodsh && skip "remote MDS with nodsh"
16060         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
16061                 skip_env "Need to mount OST to test"
16062         fi
16063
16064         local mds=$(facet_host $SINGLEMDS)
16065         local target=$(do_nodes $mds 'lctl dl' |
16066                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16067
16068         local cmd1="file_count=1000 thrhi=4"
16069         local cmd2="dir_count=2 layer=mdd stripe_count=1"
16070         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16071         local cmd="$cmd1 $cmd2 $cmd3"
16072
16073         rm -f ${TMP}/mds_survey*
16074         echo + $cmd
16075         eval $cmd || error "mds-survey with stripe_count failed"
16076         cat ${TMP}/mds_survey*
16077         rm -f ${TMP}/mds_survey*
16078 }
16079 run_test 225b "Metadata survey sanity with stripe_count = 1"
16080
16081 mcreate_path2fid () {
16082         local mode=$1
16083         local major=$2
16084         local minor=$3
16085         local name=$4
16086         local desc=$5
16087         local path=$DIR/$tdir/$name
16088         local fid
16089         local rc
16090         local fid_path
16091
16092         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
16093                 error "cannot create $desc"
16094
16095         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
16096         rc=$?
16097         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
16098
16099         fid_path=$($LFS fid2path $MOUNT $fid)
16100         rc=$?
16101         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
16102
16103         [ "$path" == "$fid_path" ] ||
16104                 error "fid2path returned $fid_path, expected $path"
16105
16106         echo "pass with $path and $fid"
16107 }
16108
16109 test_226a () {
16110         rm -rf $DIR/$tdir
16111         mkdir -p $DIR/$tdir
16112
16113         mcreate_path2fid 0010666 0 0 fifo "FIFO"
16114         mcreate_path2fid 0020666 1 3 null "character special file (null)"
16115         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
16116         mcreate_path2fid 0040666 0 0 dir "directory"
16117         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
16118         mcreate_path2fid 0100666 0 0 file "regular file"
16119         mcreate_path2fid 0120666 0 0 link "symbolic link"
16120         mcreate_path2fid 0140666 0 0 sock "socket"
16121 }
16122 run_test 226a "call path2fid and fid2path on files of all type"
16123
16124 test_226b () {
16125         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16126
16127         local MDTIDX=1
16128
16129         rm -rf $DIR/$tdir
16130         mkdir -p $DIR/$tdir
16131         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
16132                 error "create remote directory failed"
16133         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
16134         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
16135                                 "character special file (null)"
16136         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
16137                                 "character special file (no device)"
16138         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
16139         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
16140                                 "block special file (loop)"
16141         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
16142         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
16143         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
16144 }
16145 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
16146
16147 # LU-1299 Executing or running ldd on a truncated executable does not
16148 # cause an out-of-memory condition.
16149 test_227() {
16150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16151         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
16152
16153         dd if=$(which date) of=$MOUNT/date bs=1k count=1
16154         chmod +x $MOUNT/date
16155
16156         $MOUNT/date > /dev/null
16157         ldd $MOUNT/date > /dev/null
16158         rm -f $MOUNT/date
16159 }
16160 run_test 227 "running truncated executable does not cause OOM"
16161
16162 # LU-1512 try to reuse idle OI blocks
16163 test_228a() {
16164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16165         remote_mds_nodsh && skip "remote MDS with nodsh"
16166         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16167
16168         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16169         local myDIR=$DIR/$tdir
16170
16171         mkdir -p $myDIR
16172         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16173         $LCTL set_param fail_loc=0x80001002
16174         createmany -o $myDIR/t- 10000
16175         $LCTL set_param fail_loc=0
16176         # The guard is current the largest FID holder
16177         touch $myDIR/guard
16178         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16179                     tr -d '[')
16180         local IDX=$(($SEQ % 64))
16181
16182         do_facet $SINGLEMDS sync
16183         # Make sure journal flushed.
16184         sleep 6
16185         local blk1=$(do_facet $SINGLEMDS \
16186                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16187                      grep Blockcount | awk '{print $4}')
16188
16189         # Remove old files, some OI blocks will become idle.
16190         unlinkmany $myDIR/t- 10000
16191         # Create new files, idle OI blocks should be reused.
16192         createmany -o $myDIR/t- 2000
16193         do_facet $SINGLEMDS sync
16194         # Make sure journal flushed.
16195         sleep 6
16196         local blk2=$(do_facet $SINGLEMDS \
16197                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16198                      grep Blockcount | awk '{print $4}')
16199
16200         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16201 }
16202 run_test 228a "try to reuse idle OI blocks"
16203
16204 test_228b() {
16205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16206         remote_mds_nodsh && skip "remote MDS with nodsh"
16207         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16208
16209         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16210         local myDIR=$DIR/$tdir
16211
16212         mkdir -p $myDIR
16213         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16214         $LCTL set_param fail_loc=0x80001002
16215         createmany -o $myDIR/t- 10000
16216         $LCTL set_param fail_loc=0
16217         # The guard is current the largest FID holder
16218         touch $myDIR/guard
16219         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16220                     tr -d '[')
16221         local IDX=$(($SEQ % 64))
16222
16223         do_facet $SINGLEMDS sync
16224         # Make sure journal flushed.
16225         sleep 6
16226         local blk1=$(do_facet $SINGLEMDS \
16227                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16228                      grep Blockcount | awk '{print $4}')
16229
16230         # Remove old files, some OI blocks will become idle.
16231         unlinkmany $myDIR/t- 10000
16232
16233         # stop the MDT
16234         stop $SINGLEMDS || error "Fail to stop MDT."
16235         # remount the MDT
16236         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
16237
16238         df $MOUNT || error "Fail to df."
16239         # Create new files, idle OI blocks should be reused.
16240         createmany -o $myDIR/t- 2000
16241         do_facet $SINGLEMDS sync
16242         # Make sure journal flushed.
16243         sleep 6
16244         local blk2=$(do_facet $SINGLEMDS \
16245                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16246                      grep Blockcount | awk '{print $4}')
16247
16248         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16249 }
16250 run_test 228b "idle OI blocks can be reused after MDT restart"
16251
16252 #LU-1881
16253 test_228c() {
16254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16255         remote_mds_nodsh && skip "remote MDS with nodsh"
16256         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16257
16258         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16259         local myDIR=$DIR/$tdir
16260
16261         mkdir -p $myDIR
16262         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16263         $LCTL set_param fail_loc=0x80001002
16264         # 20000 files can guarantee there are index nodes in the OI file
16265         createmany -o $myDIR/t- 20000
16266         $LCTL set_param fail_loc=0
16267         # The guard is current the largest FID holder
16268         touch $myDIR/guard
16269         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16270                     tr -d '[')
16271         local IDX=$(($SEQ % 64))
16272
16273         do_facet $SINGLEMDS sync
16274         # Make sure journal flushed.
16275         sleep 6
16276         local blk1=$(do_facet $SINGLEMDS \
16277                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16278                      grep Blockcount | awk '{print $4}')
16279
16280         # Remove old files, some OI blocks will become idle.
16281         unlinkmany $myDIR/t- 20000
16282         rm -f $myDIR/guard
16283         # The OI file should become empty now
16284
16285         # Create new files, idle OI blocks should be reused.
16286         createmany -o $myDIR/t- 2000
16287         do_facet $SINGLEMDS sync
16288         # Make sure journal flushed.
16289         sleep 6
16290         local blk2=$(do_facet $SINGLEMDS \
16291                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16292                      grep Blockcount | awk '{print $4}')
16293
16294         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16295 }
16296 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
16297
16298 test_229() { # LU-2482, LU-3448
16299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16300         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
16301         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
16302                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
16303
16304         rm -f $DIR/$tfile
16305
16306         # Create a file with a released layout and stripe count 2.
16307         $MULTIOP $DIR/$tfile H2c ||
16308                 error "failed to create file with released layout"
16309
16310         $LFS getstripe -v $DIR/$tfile
16311
16312         local pattern=$($LFS getstripe -L $DIR/$tfile)
16313         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
16314
16315         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
16316                 error "getstripe"
16317         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
16318         stat $DIR/$tfile || error "failed to stat released file"
16319
16320         chown $RUNAS_ID $DIR/$tfile ||
16321                 error "chown $RUNAS_ID $DIR/$tfile failed"
16322
16323         chgrp $RUNAS_ID $DIR/$tfile ||
16324                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
16325
16326         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
16327         rm $DIR/$tfile || error "failed to remove released file"
16328 }
16329 run_test 229 "getstripe/stat/rm/attr changes work on released files"
16330
16331 test_230a() {
16332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16334         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16335                 skip "Need MDS version at least 2.11.52"
16336
16337         local MDTIDX=1
16338
16339         test_mkdir $DIR/$tdir
16340         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
16341         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
16342         [ $mdt_idx -ne 0 ] &&
16343                 error "create local directory on wrong MDT $mdt_idx"
16344
16345         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
16346                         error "create remote directory failed"
16347         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
16348         [ $mdt_idx -ne $MDTIDX ] &&
16349                 error "create remote directory on wrong MDT $mdt_idx"
16350
16351         createmany -o $DIR/$tdir/test_230/t- 10 ||
16352                 error "create files on remote directory failed"
16353         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
16354         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
16355         rm -r $DIR/$tdir || error "unlink remote directory failed"
16356 }
16357 run_test 230a "Create remote directory and files under the remote directory"
16358
16359 test_230b() {
16360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16361         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16362         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16363                 skip "Need MDS version at least 2.11.52"
16364
16365         local MDTIDX=1
16366         local mdt_index
16367         local i
16368         local file
16369         local pid
16370         local stripe_count
16371         local migrate_dir=$DIR/$tdir/migrate_dir
16372         local other_dir=$DIR/$tdir/other_dir
16373
16374         test_mkdir $DIR/$tdir
16375         test_mkdir -i0 -c1 $migrate_dir
16376         test_mkdir -i0 -c1 $other_dir
16377         for ((i=0; i<10; i++)); do
16378                 mkdir -p $migrate_dir/dir_${i}
16379                 createmany -o $migrate_dir/dir_${i}/f 10 ||
16380                         error "create files under remote dir failed $i"
16381         done
16382
16383         cp /etc/passwd $migrate_dir/$tfile
16384         cp /etc/passwd $other_dir/$tfile
16385         chattr +SAD $migrate_dir
16386         chattr +SAD $migrate_dir/$tfile
16387
16388         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16389         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16390         local old_dir_mode=$(stat -c%f $migrate_dir)
16391         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
16392
16393         mkdir -p $migrate_dir/dir_default_stripe2
16394         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
16395         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
16396
16397         mkdir -p $other_dir
16398         ln $migrate_dir/$tfile $other_dir/luna
16399         ln $migrate_dir/$tfile $migrate_dir/sofia
16400         ln $other_dir/$tfile $migrate_dir/david
16401         ln -s $migrate_dir/$tfile $other_dir/zachary
16402         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
16403         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
16404
16405         $LFS migrate -m $MDTIDX $migrate_dir ||
16406                 error "fails on migrating remote dir to MDT1"
16407
16408         echo "migratate to MDT1, then checking.."
16409         for ((i = 0; i < 10; i++)); do
16410                 for file in $(find $migrate_dir/dir_${i}); do
16411                         mdt_index=$($LFS getstripe -m $file)
16412                         [ $mdt_index == $MDTIDX ] ||
16413                                 error "$file is not on MDT${MDTIDX}"
16414                 done
16415         done
16416
16417         # the multiple link file should still in MDT0
16418         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
16419         [ $mdt_index == 0 ] ||
16420                 error "$file is not on MDT${MDTIDX}"
16421
16422         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16423         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16424                 error " expect $old_dir_flag get $new_dir_flag"
16425
16426         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16427         [ "$old_file_flag" = "$new_file_flag" ] ||
16428                 error " expect $old_file_flag get $new_file_flag"
16429
16430         local new_dir_mode=$(stat -c%f $migrate_dir)
16431         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16432                 error "expect mode $old_dir_mode get $new_dir_mode"
16433
16434         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16435         [ "$old_file_mode" = "$new_file_mode" ] ||
16436                 error "expect mode $old_file_mode get $new_file_mode"
16437
16438         diff /etc/passwd $migrate_dir/$tfile ||
16439                 error "$tfile different after migration"
16440
16441         diff /etc/passwd $other_dir/luna ||
16442                 error "luna different after migration"
16443
16444         diff /etc/passwd $migrate_dir/sofia ||
16445                 error "sofia different after migration"
16446
16447         diff /etc/passwd $migrate_dir/david ||
16448                 error "david different after migration"
16449
16450         diff /etc/passwd $other_dir/zachary ||
16451                 error "zachary different after migration"
16452
16453         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16454                 error "${tfile}_ln different after migration"
16455
16456         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16457                 error "${tfile}_ln_other different after migration"
16458
16459         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
16460         [ $stripe_count = 2 ] ||
16461                 error "dir strpe_count $d != 2 after migration."
16462
16463         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
16464         [ $stripe_count = 2 ] ||
16465                 error "file strpe_count $d != 2 after migration."
16466
16467         #migrate back to MDT0
16468         MDTIDX=0
16469
16470         $LFS migrate -m $MDTIDX $migrate_dir ||
16471                 error "fails on migrating remote dir to MDT0"
16472
16473         echo "migrate back to MDT0, checking.."
16474         for file in $(find $migrate_dir); do
16475                 mdt_index=$($LFS getstripe -m $file)
16476                 [ $mdt_index == $MDTIDX ] ||
16477                         error "$file is not on MDT${MDTIDX}"
16478         done
16479
16480         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16481         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16482                 error " expect $old_dir_flag get $new_dir_flag"
16483
16484         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16485         [ "$old_file_flag" = "$new_file_flag" ] ||
16486                 error " expect $old_file_flag get $new_file_flag"
16487
16488         local new_dir_mode=$(stat -c%f $migrate_dir)
16489         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16490                 error "expect mode $old_dir_mode get $new_dir_mode"
16491
16492         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16493         [ "$old_file_mode" = "$new_file_mode" ] ||
16494                 error "expect mode $old_file_mode get $new_file_mode"
16495
16496         diff /etc/passwd ${migrate_dir}/$tfile ||
16497                 error "$tfile different after migration"
16498
16499         diff /etc/passwd ${other_dir}/luna ||
16500                 error "luna different after migration"
16501
16502         diff /etc/passwd ${migrate_dir}/sofia ||
16503                 error "sofia different after migration"
16504
16505         diff /etc/passwd ${other_dir}/zachary ||
16506                 error "zachary different after migration"
16507
16508         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16509                 error "${tfile}_ln different after migration"
16510
16511         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16512                 error "${tfile}_ln_other different after migration"
16513
16514         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
16515         [ $stripe_count = 2 ] ||
16516                 error "dir strpe_count $d != 2 after migration."
16517
16518         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
16519         [ $stripe_count = 2 ] ||
16520                 error "file strpe_count $d != 2 after migration."
16521
16522         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16523 }
16524 run_test 230b "migrate directory"
16525
16526 test_230c() {
16527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16528         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16529         remote_mds_nodsh && skip "remote MDS with nodsh"
16530         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16531                 skip "Need MDS version at least 2.11.52"
16532
16533         local MDTIDX=1
16534         local total=3
16535         local mdt_index
16536         local file
16537         local migrate_dir=$DIR/$tdir/migrate_dir
16538
16539         #If migrating directory fails in the middle, all entries of
16540         #the directory is still accessiable.
16541         test_mkdir $DIR/$tdir
16542         test_mkdir -i0 -c1 $migrate_dir
16543         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
16544         stat $migrate_dir
16545         createmany -o $migrate_dir/f $total ||
16546                 error "create files under ${migrate_dir} failed"
16547
16548         # fail after migrating top dir, and this will fail only once, so the
16549         # first sub file migration will fail (currently f3), others succeed.
16550         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16551         do_facet mds1 lctl set_param fail_loc=0x1801
16552         local t=$(ls $migrate_dir | wc -l)
16553         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
16554                 error "migrate should fail"
16555         local u=$(ls $migrate_dir | wc -l)
16556         [ "$u" == "$t" ] || error "$u != $t during migration"
16557
16558         # add new dir/file should succeed
16559         mkdir $migrate_dir/dir ||
16560                 error "mkdir failed under migrating directory"
16561         touch $migrate_dir/file ||
16562                 error "create file failed under migrating directory"
16563
16564         # add file with existing name should fail
16565         for file in $migrate_dir/f*; do
16566                 stat $file > /dev/null || error "stat $file failed"
16567                 $OPENFILE -f O_CREAT:O_EXCL $file &&
16568                         error "open(O_CREAT|O_EXCL) $file should fail"
16569                 $MULTIOP $file m && error "create $file should fail"
16570                 touch $DIR/$tdir/remote_dir/$tfile ||
16571                         error "touch $tfile failed"
16572                 ln $DIR/$tdir/remote_dir/$tfile $file &&
16573                         error "link $file should fail"
16574                 mdt_index=$($LFS getstripe -m $file)
16575                 if [ $mdt_index == 0 ]; then
16576                         # file failed to migrate is not allowed to rename to
16577                         mv $DIR/$tdir/remote_dir/$tfile $file &&
16578                                 error "rename to $file should fail"
16579                 else
16580                         mv $DIR/$tdir/remote_dir/$tfile $file ||
16581                                 error "rename to $file failed"
16582                 fi
16583                 echo hello >> $file || error "write $file failed"
16584         done
16585
16586         # resume migration with different options should fail
16587         $LFS migrate -m 0 $migrate_dir &&
16588                 error "migrate -m 0 $migrate_dir should fail"
16589
16590         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
16591                 error "migrate -c 2 $migrate_dir should fail"
16592
16593         # resume migration should succeed
16594         $LFS migrate -m $MDTIDX $migrate_dir ||
16595                 error "migrate $migrate_dir failed"
16596
16597         echo "Finish migration, then checking.."
16598         for file in $(find $migrate_dir); do
16599                 mdt_index=$($LFS getstripe -m $file)
16600                 [ $mdt_index == $MDTIDX ] ||
16601                         error "$file is not on MDT${MDTIDX}"
16602         done
16603
16604         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16605 }
16606 run_test 230c "check directory accessiblity if migration failed"
16607
16608 test_230d() {
16609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16610         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16611         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16612                 skip "Need MDS version at least 2.11.52"
16613         # LU-11235
16614         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
16615
16616         local migrate_dir=$DIR/$tdir/migrate_dir
16617         local old_index
16618         local new_index
16619         local old_count
16620         local new_count
16621         local new_hash
16622         local mdt_index
16623         local i
16624         local j
16625
16626         old_index=$((RANDOM % MDSCOUNT))
16627         old_count=$((MDSCOUNT - old_index))
16628         new_index=$((RANDOM % MDSCOUNT))
16629         new_count=$((MDSCOUNT - new_index))
16630         new_hash="all_char"
16631
16632         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
16633         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
16634
16635         test_mkdir $DIR/$tdir
16636         test_mkdir -i $old_index -c $old_count $migrate_dir
16637
16638         for ((i=0; i<100; i++)); do
16639                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
16640                 createmany -o $migrate_dir/dir_${i}/f 100 ||
16641                         error "create files under remote dir failed $i"
16642         done
16643
16644         echo -n "Migrate from MDT$old_index "
16645         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
16646         echo -n "to MDT$new_index"
16647         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16648         echo
16649
16650         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16651         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16652                 error "migrate remote dir error"
16653
16654         echo "Finish migration, then checking.."
16655         for file in $(find $migrate_dir); do
16656                 mdt_index=$($LFS getstripe -m $file)
16657                 if [ $mdt_index -lt $new_index ] ||
16658                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16659                         error "$file is on MDT$mdt_index"
16660                 fi
16661         done
16662
16663         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16664 }
16665 run_test 230d "check migrate big directory"
16666
16667 test_230e() {
16668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16669         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16670         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16671                 skip "Need MDS version at least 2.11.52"
16672
16673         local i
16674         local j
16675         local a_fid
16676         local b_fid
16677
16678         mkdir -p $DIR/$tdir
16679         mkdir $DIR/$tdir/migrate_dir
16680         mkdir $DIR/$tdir/other_dir
16681         touch $DIR/$tdir/migrate_dir/a
16682         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16683         ls $DIR/$tdir/other_dir
16684
16685         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16686                 error "migrate dir fails"
16687
16688         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16689         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16690
16691         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16692         [ $mdt_index == 0 ] || error "a is not on MDT0"
16693
16694         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16695                 error "migrate dir fails"
16696
16697         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16698         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16699
16700         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16701         [ $mdt_index == 1 ] || error "a is not on MDT1"
16702
16703         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16704         [ $mdt_index == 1 ] || error "b is not on MDT1"
16705
16706         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16707         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16708
16709         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16710
16711         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16712 }
16713 run_test 230e "migrate mulitple local link files"
16714
16715 test_230f() {
16716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16717         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16718         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16719                 skip "Need MDS version at least 2.11.52"
16720
16721         local a_fid
16722         local ln_fid
16723
16724         mkdir -p $DIR/$tdir
16725         mkdir $DIR/$tdir/migrate_dir
16726         $LFS mkdir -i1 $DIR/$tdir/other_dir
16727         touch $DIR/$tdir/migrate_dir/a
16728         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16729         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16730         ls $DIR/$tdir/other_dir
16731
16732         # a should be migrated to MDT1, since no other links on MDT0
16733         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16734                 error "#1 migrate dir fails"
16735         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16736         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16737         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16738         [ $mdt_index == 1 ] || error "a is not on MDT1"
16739
16740         # a should stay on MDT1, because it is a mulitple link file
16741         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16742                 error "#2 migrate dir fails"
16743         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16744         [ $mdt_index == 1 ] || error "a is not on MDT1"
16745
16746         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16747                 error "#3 migrate dir fails"
16748
16749         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16750         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16751         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16752
16753         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16754         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16755
16756         # a should be migrated to MDT0, since no other links on MDT1
16757         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16758                 error "#4 migrate dir fails"
16759         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16760         [ $mdt_index == 0 ] || error "a is not on MDT0"
16761
16762         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16763 }
16764 run_test 230f "migrate mulitple remote link files"
16765
16766 test_230g() {
16767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16768         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16769         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16770                 skip "Need MDS version at least 2.11.52"
16771
16772         mkdir -p $DIR/$tdir/migrate_dir
16773
16774         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16775                 error "migrating dir to non-exist MDT succeeds"
16776         true
16777 }
16778 run_test 230g "migrate dir to non-exist MDT"
16779
16780 test_230h() {
16781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16782         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16783         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16784                 skip "Need MDS version at least 2.11.52"
16785
16786         local mdt_index
16787
16788         mkdir -p $DIR/$tdir/migrate_dir
16789
16790         $LFS migrate -m1 $DIR &&
16791                 error "migrating mountpoint1 should fail"
16792
16793         $LFS migrate -m1 $DIR/$tdir/.. &&
16794                 error "migrating mountpoint2 should fail"
16795
16796         # same as mv
16797         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16798                 error "migrating $tdir/migrate_dir/.. should fail"
16799
16800         true
16801 }
16802 run_test 230h "migrate .. and root"
16803
16804 test_230i() {
16805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16806         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16807         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16808                 skip "Need MDS version at least 2.11.52"
16809
16810         mkdir -p $DIR/$tdir/migrate_dir
16811
16812         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16813                 error "migration fails with a tailing slash"
16814
16815         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16816                 error "migration fails with two tailing slashes"
16817 }
16818 run_test 230i "lfs migrate -m tolerates trailing slashes"
16819
16820 test_230j() {
16821         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16822         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16823                 skip "Need MDS version at least 2.11.52"
16824
16825         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16826         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16827                 error "create $tfile failed"
16828         cat /etc/passwd > $DIR/$tdir/$tfile
16829
16830         $LFS migrate -m 1 $DIR/$tdir
16831
16832         cmp /etc/passwd $DIR/$tdir/$tfile ||
16833                 error "DoM file mismatch after migration"
16834 }
16835 run_test 230j "DoM file data not changed after dir migration"
16836
16837 test_230k() {
16838         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16839         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16840                 skip "Need MDS version at least 2.11.56"
16841
16842         local total=20
16843         local files_on_starting_mdt=0
16844
16845         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16846         $LFS getdirstripe $DIR/$tdir
16847         for i in $(seq $total); do
16848                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16849                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16850                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16851         done
16852
16853         echo "$files_on_starting_mdt files on MDT0"
16854
16855         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16856         $LFS getdirstripe $DIR/$tdir
16857
16858         files_on_starting_mdt=0
16859         for i in $(seq $total); do
16860                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16861                         error "file $tfile.$i mismatch after migration"
16862                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16863                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16864         done
16865
16866         echo "$files_on_starting_mdt files on MDT1 after migration"
16867         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16868
16869         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16870         $LFS getdirstripe $DIR/$tdir
16871
16872         files_on_starting_mdt=0
16873         for i in $(seq $total); do
16874                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16875                         error "file $tfile.$i mismatch after 2nd migration"
16876                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16877                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16878         done
16879
16880         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16881         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16882
16883         true
16884 }
16885 run_test 230k "file data not changed after dir migration"
16886
16887 test_230l() {
16888         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16889         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16890                 skip "Need MDS version at least 2.11.56"
16891
16892         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16893         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16894                 error "create files under remote dir failed $i"
16895         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16896 }
16897 run_test 230l "readdir between MDTs won't crash"
16898
16899 test_231a()
16900 {
16901         # For simplicity this test assumes that max_pages_per_rpc
16902         # is the same across all OSCs
16903         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16904         local bulk_size=$((max_pages * PAGE_SIZE))
16905         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16906                                        head -n 1)
16907
16908         mkdir -p $DIR/$tdir
16909         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16910                 error "failed to set stripe with -S ${brw_size}M option"
16911
16912         # clear the OSC stats
16913         $LCTL set_param osc.*.stats=0 &>/dev/null
16914         stop_writeback
16915
16916         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
16917         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
16918                 oflag=direct &>/dev/null || error "dd failed"
16919
16920         sync; sleep 1; sync # just to be safe
16921         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
16922         if [ x$nrpcs != "x1" ]; then
16923                 $LCTL get_param osc.*.stats
16924                 error "found $nrpcs ost_write RPCs, not 1 as expected"
16925         fi
16926
16927         start_writeback
16928         # Drop the OSC cache, otherwise we will read from it
16929         cancel_lru_locks osc
16930
16931         # clear the OSC stats
16932         $LCTL set_param osc.*.stats=0 &>/dev/null
16933
16934         # Client reads $bulk_size.
16935         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
16936                 iflag=direct &>/dev/null || error "dd failed"
16937
16938         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
16939         if [ x$nrpcs != "x1" ]; then
16940                 $LCTL get_param osc.*.stats
16941                 error "found $nrpcs ost_read RPCs, not 1 as expected"
16942         fi
16943 }
16944 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
16945
16946 test_231b() {
16947         mkdir -p $DIR/$tdir
16948         local i
16949         for i in {0..1023}; do
16950                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
16951                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
16952                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
16953         done
16954         sync
16955 }
16956 run_test 231b "must not assert on fully utilized OST request buffer"
16957
16958 test_232a() {
16959         mkdir -p $DIR/$tdir
16960         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16961
16962         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16963         do_facet ost1 $LCTL set_param fail_loc=0x31c
16964
16965         # ignore dd failure
16966         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
16967
16968         do_facet ost1 $LCTL set_param fail_loc=0
16969         umount_client $MOUNT || error "umount failed"
16970         mount_client $MOUNT || error "mount failed"
16971         stop ost1 || error "cannot stop ost1"
16972         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16973 }
16974 run_test 232a "failed lock should not block umount"
16975
16976 test_232b() {
16977         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
16978                 skip "Need MDS version at least 2.10.58"
16979
16980         mkdir -p $DIR/$tdir
16981         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16982         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
16983         sync
16984         cancel_lru_locks osc
16985
16986         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16987         do_facet ost1 $LCTL set_param fail_loc=0x31c
16988
16989         # ignore failure
16990         $LFS data_version $DIR/$tdir/$tfile || true
16991
16992         do_facet ost1 $LCTL set_param fail_loc=0
16993         umount_client $MOUNT || error "umount failed"
16994         mount_client $MOUNT || error "mount failed"
16995         stop ost1 || error "cannot stop ost1"
16996         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16997 }
16998 run_test 232b "failed data version lock should not block umount"
16999
17000 test_233a() {
17001         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
17002                 skip "Need MDS version at least 2.3.64"
17003         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17004
17005         local fid=$($LFS path2fid $MOUNT)
17006
17007         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17008                 error "cannot access $MOUNT using its FID '$fid'"
17009 }
17010 run_test 233a "checking that OBF of the FS root succeeds"
17011
17012 test_233b() {
17013         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
17014                 skip "Need MDS version at least 2.5.90"
17015         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17016
17017         local fid=$($LFS path2fid $MOUNT/.lustre)
17018
17019         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17020                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
17021
17022         fid=$($LFS path2fid $MOUNT/.lustre/fid)
17023         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17024                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
17025 }
17026 run_test 233b "checking that OBF of the FS .lustre succeeds"
17027
17028 test_234() {
17029         local p="$TMP/sanityN-$TESTNAME.parameters"
17030         save_lustre_params client "llite.*.xattr_cache" > $p
17031         lctl set_param llite.*.xattr_cache 1 ||
17032                 skip_env "xattr cache is not supported"
17033
17034         mkdir -p $DIR/$tdir || error "mkdir failed"
17035         touch $DIR/$tdir/$tfile || error "touch failed"
17036         # OBD_FAIL_LLITE_XATTR_ENOMEM
17037         $LCTL set_param fail_loc=0x1405
17038         getfattr -n user.attr $DIR/$tdir/$tfile &&
17039                 error "getfattr should have failed with ENOMEM"
17040         $LCTL set_param fail_loc=0x0
17041         rm -rf $DIR/$tdir
17042
17043         restore_lustre_params < $p
17044         rm -f $p
17045 }
17046 run_test 234 "xattr cache should not crash on ENOMEM"
17047
17048 test_235() {
17049         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
17050                 skip "Need MDS version at least 2.4.52"
17051
17052         flock_deadlock $DIR/$tfile
17053         local RC=$?
17054         case $RC in
17055                 0)
17056                 ;;
17057                 124) error "process hangs on a deadlock"
17058                 ;;
17059                 *) error "error executing flock_deadlock $DIR/$tfile"
17060                 ;;
17061         esac
17062 }
17063 run_test 235 "LU-1715: flock deadlock detection does not work properly"
17064
17065 #LU-2935
17066 test_236() {
17067         check_swap_layouts_support
17068
17069         local ref1=/etc/passwd
17070         local ref2=/etc/group
17071         local file1=$DIR/$tdir/f1
17072         local file2=$DIR/$tdir/f2
17073
17074         test_mkdir -c1 $DIR/$tdir
17075         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
17076         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
17077         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
17078         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
17079         local fd=$(free_fd)
17080         local cmd="exec $fd<>$file2"
17081         eval $cmd
17082         rm $file2
17083         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
17084                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
17085         cmd="exec $fd>&-"
17086         eval $cmd
17087         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17088
17089         #cleanup
17090         rm -rf $DIR/$tdir
17091 }
17092 run_test 236 "Layout swap on open unlinked file"
17093
17094 # LU-4659 linkea consistency
17095 test_238() {
17096         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17097                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17098                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17099                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17100
17101         touch $DIR/$tfile
17102         ln $DIR/$tfile $DIR/$tfile.lnk
17103         touch $DIR/$tfile.new
17104         mv $DIR/$tfile.new $DIR/$tfile
17105         local fid1=$($LFS path2fid $DIR/$tfile)
17106         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
17107         local path1=$($LFS fid2path $FSNAME "$fid1")
17108         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
17109         local path2=$($LFS fid2path $FSNAME "$fid2")
17110         [ $tfile.lnk == $path2 ] ||
17111                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
17112         rm -f $DIR/$tfile*
17113 }
17114 run_test 238 "Verify linkea consistency"
17115
17116 test_239A() { # was test_239
17117         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
17118                 skip "Need MDS version at least 2.5.60"
17119
17120         local list=$(comma_list $(mdts_nodes))
17121
17122         mkdir -p $DIR/$tdir
17123         createmany -o $DIR/$tdir/f- 5000
17124         unlinkmany $DIR/$tdir/f- 5000
17125         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
17126                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
17127         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
17128                         osp.*MDT*.sync_in_flight" | calc_sum)
17129         [ "$changes" -eq 0 ] || error "$changes not synced"
17130 }
17131 run_test 239A "osp_sync test"
17132
17133 test_239a() { #LU-5297
17134         remote_mds_nodsh && skip "remote MDS with nodsh"
17135
17136         touch $DIR/$tfile
17137         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
17138         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
17139         chgrp $RUNAS_GID $DIR/$tfile
17140         wait_delete_completed
17141 }
17142 run_test 239a "process invalid osp sync record correctly"
17143
17144 test_239b() { #LU-5297
17145         remote_mds_nodsh && skip "remote MDS with nodsh"
17146
17147         touch $DIR/$tfile1
17148         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
17149         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
17150         chgrp $RUNAS_GID $DIR/$tfile1
17151         wait_delete_completed
17152         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17153         touch $DIR/$tfile2
17154         chgrp $RUNAS_GID $DIR/$tfile2
17155         wait_delete_completed
17156 }
17157 run_test 239b "process osp sync record with ENOMEM error correctly"
17158
17159 test_240() {
17160         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17161         remote_mds_nodsh && skip "remote MDS with nodsh"
17162
17163         mkdir -p $DIR/$tdir
17164
17165         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
17166                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
17167         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
17168                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
17169
17170         umount_client $MOUNT || error "umount failed"
17171         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
17172         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
17173         mount_client $MOUNT || error "failed to mount client"
17174
17175         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
17176         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
17177 }
17178 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
17179
17180 test_241_bio() {
17181         local count=$1
17182         local bsize=$2
17183
17184         for LOOP in $(seq $count); do
17185                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
17186                 cancel_lru_locks $OSC || true
17187         done
17188 }
17189
17190 test_241_dio() {
17191         local count=$1
17192         local bsize=$2
17193
17194         for LOOP in $(seq $1); do
17195                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
17196                         2>/dev/null
17197         done
17198 }
17199
17200 test_241a() { # was test_241
17201         local bsize=$PAGE_SIZE
17202
17203         (( bsize < 40960 )) && bsize=40960
17204         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17205         ls -la $DIR/$tfile
17206         cancel_lru_locks $OSC
17207         test_241_bio 1000 $bsize &
17208         PID=$!
17209         test_241_dio 1000 $bsize
17210         wait $PID
17211 }
17212 run_test 241a "bio vs dio"
17213
17214 test_241b() {
17215         local bsize=$PAGE_SIZE
17216
17217         (( bsize < 40960 )) && bsize=40960
17218         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17219         ls -la $DIR/$tfile
17220         test_241_dio 1000 $bsize &
17221         PID=$!
17222         test_241_dio 1000 $bsize
17223         wait $PID
17224 }
17225 run_test 241b "dio vs dio"
17226
17227 test_242() {
17228         remote_mds_nodsh && skip "remote MDS with nodsh"
17229
17230         mkdir -p $DIR/$tdir
17231         touch $DIR/$tdir/$tfile
17232
17233         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
17234         do_facet mds1 lctl set_param fail_loc=0x105
17235         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
17236
17237         do_facet mds1 lctl set_param fail_loc=0
17238         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
17239 }
17240 run_test 242 "mdt_readpage failure should not cause directory unreadable"
17241
17242 test_243()
17243 {
17244         test_mkdir $DIR/$tdir
17245         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
17246 }
17247 run_test 243 "various group lock tests"
17248
17249 test_244a()
17250 {
17251         test_mkdir $DIR/$tdir
17252         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
17253         sendfile_grouplock $DIR/$tdir/$tfile || \
17254                 error "sendfile+grouplock failed"
17255         rm -rf $DIR/$tdir
17256 }
17257 run_test 244a "sendfile with group lock tests"
17258
17259 test_244b()
17260 {
17261         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17262
17263         local threads=50
17264         local size=$((1024*1024))
17265
17266         test_mkdir $DIR/$tdir
17267         for i in $(seq 1 $threads); do
17268                 local file=$DIR/$tdir/file_$((i / 10))
17269                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
17270                 local pids[$i]=$!
17271         done
17272         for i in $(seq 1 $threads); do
17273                 wait ${pids[$i]}
17274         done
17275 }
17276 run_test 244b "multi-threaded write with group lock"
17277
17278 test_245() {
17279         local flagname="multi_mod_rpcs"
17280         local connect_data_name="max_mod_rpcs"
17281         local out
17282
17283         # check if multiple modify RPCs flag is set
17284         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
17285                 grep "connect_flags:")
17286         echo "$out"
17287
17288         echo "$out" | grep -qw $flagname
17289         if [ $? -ne 0 ]; then
17290                 echo "connect flag $flagname is not set"
17291                 return
17292         fi
17293
17294         # check if multiple modify RPCs data is set
17295         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
17296         echo "$out"
17297
17298         echo "$out" | grep -qw $connect_data_name ||
17299                 error "import should have connect data $connect_data_name"
17300 }
17301 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
17302
17303 test_246() { # LU-7371
17304         remote_ost_nodsh && skip "remote OST with nodsh"
17305         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
17306                 skip "Need OST version >= 2.7.62"
17307
17308         do_facet ost1 $LCTL set_param fail_val=4095
17309 #define OBD_FAIL_OST_READ_SIZE          0x234
17310         do_facet ost1 $LCTL set_param fail_loc=0x234
17311         $LFS setstripe $DIR/$tfile -i 0 -c 1
17312         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
17313         cancel_lru_locks $FSNAME-OST0000
17314         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
17315 }
17316 run_test 246 "Read file of size 4095 should return right length"
17317
17318 cleanup_247() {
17319         local submount=$1
17320
17321         trap 0
17322         umount_client $submount
17323         rmdir $submount
17324 }
17325
17326 test_247a() {
17327         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17328                 grep -q subtree ||
17329                 skip_env "Fileset feature is not supported"
17330
17331         local submount=${MOUNT}_$tdir
17332
17333         mkdir $MOUNT/$tdir
17334         mkdir -p $submount || error "mkdir $submount failed"
17335         FILESET="$FILESET/$tdir" mount_client $submount ||
17336                 error "mount $submount failed"
17337         trap "cleanup_247 $submount" EXIT
17338         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
17339         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
17340                 error "read $MOUNT/$tdir/$tfile failed"
17341         cleanup_247 $submount
17342 }
17343 run_test 247a "mount subdir as fileset"
17344
17345 test_247b() {
17346         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17347                 skip_env "Fileset feature is not supported"
17348
17349         local submount=${MOUNT}_$tdir
17350
17351         rm -rf $MOUNT/$tdir
17352         mkdir -p $submount || error "mkdir $submount failed"
17353         SKIP_FILESET=1
17354         FILESET="$FILESET/$tdir" mount_client $submount &&
17355                 error "mount $submount should fail"
17356         rmdir $submount
17357 }
17358 run_test 247b "mount subdir that dose not exist"
17359
17360 test_247c() {
17361         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17362                 skip_env "Fileset feature is not supported"
17363
17364         local submount=${MOUNT}_$tdir
17365
17366         mkdir -p $MOUNT/$tdir/dir1
17367         mkdir -p $submount || error "mkdir $submount failed"
17368         trap "cleanup_247 $submount" EXIT
17369         FILESET="$FILESET/$tdir" mount_client $submount ||
17370                 error "mount $submount failed"
17371         local fid=$($LFS path2fid $MOUNT/)
17372         $LFS fid2path $submount $fid && error "fid2path should fail"
17373         cleanup_247 $submount
17374 }
17375 run_test 247c "running fid2path outside root"
17376
17377 test_247d() {
17378         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17379                 skip "Fileset feature is not supported"
17380
17381         local submount=${MOUNT}_$tdir
17382
17383         mkdir -p $MOUNT/$tdir/dir1
17384         mkdir -p $submount || error "mkdir $submount failed"
17385         FILESET="$FILESET/$tdir" mount_client $submount ||
17386                 error "mount $submount failed"
17387         trap "cleanup_247 $submount" EXIT
17388         local fid=$($LFS path2fid $submount/dir1)
17389         $LFS fid2path $submount $fid || error "fid2path should succeed"
17390         cleanup_247 $submount
17391 }
17392 run_test 247d "running fid2path inside root"
17393
17394 # LU-8037
17395 test_247e() {
17396         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17397                 grep -q subtree ||
17398                 skip "Fileset feature is not supported"
17399
17400         local submount=${MOUNT}_$tdir
17401
17402         mkdir $MOUNT/$tdir
17403         mkdir -p $submount || error "mkdir $submount failed"
17404         FILESET="$FILESET/.." mount_client $submount &&
17405                 error "mount $submount should fail"
17406         rmdir $submount
17407 }
17408 run_test 247e "mount .. as fileset"
17409
17410 test_248() {
17411         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
17412         [ -z "$fast_read_sav" ] && skip "no fast read support"
17413
17414         # create a large file for fast read verification
17415         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
17416
17417         # make sure the file is created correctly
17418         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
17419                 { rm -f $DIR/$tfile; skip "file creation error"; }
17420
17421         echo "Test 1: verify that fast read is 4 times faster on cache read"
17422
17423         # small read with fast read enabled
17424         $LCTL set_param -n llite.*.fast_read=1
17425         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17426                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17427                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17428         # small read with fast read disabled
17429         $LCTL set_param -n llite.*.fast_read=0
17430         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17431                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17432                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17433
17434         # verify that fast read is 4 times faster for cache read
17435         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
17436                 error_not_in_vm "fast read was not 4 times faster: " \
17437                            "$t_fast vs $t_slow"
17438
17439         echo "Test 2: verify the performance between big and small read"
17440         $LCTL set_param -n llite.*.fast_read=1
17441
17442         # 1k non-cache read
17443         cancel_lru_locks osc
17444         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17445                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17446                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17447
17448         # 1M non-cache read
17449         cancel_lru_locks osc
17450         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17451                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17452                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17453
17454         # verify that big IO is not 4 times faster than small IO
17455         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
17456                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
17457
17458         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
17459         rm -f $DIR/$tfile
17460 }
17461 run_test 248 "fast read verification"
17462
17463 test_249() { # LU-7890
17464         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
17465                 skip "Need at least version 2.8.54"
17466
17467         rm -f $DIR/$tfile
17468         $LFS setstripe -c 1 $DIR/$tfile
17469         # Offset 2T == 4k * 512M
17470         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
17471                 error "dd to 2T offset failed"
17472 }
17473 run_test 249 "Write above 2T file size"
17474
17475 test_250() {
17476         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
17477          && skip "no 16TB file size limit on ZFS"
17478
17479         $LFS setstripe -c 1 $DIR/$tfile
17480         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
17481         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
17482         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
17483         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
17484                 conv=notrunc,fsync && error "append succeeded"
17485         return 0
17486 }
17487 run_test 250 "Write above 16T limit"
17488
17489 test_251() {
17490         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
17491
17492         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
17493         #Skip once - writing the first stripe will succeed
17494         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17495         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
17496                 error "short write happened"
17497
17498         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17499         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
17500                 error "short read happened"
17501
17502         rm -f $DIR/$tfile
17503 }
17504 run_test 251 "Handling short read and write correctly"
17505
17506 test_252() {
17507         remote_mds_nodsh && skip "remote MDS with nodsh"
17508         remote_ost_nodsh && skip "remote OST with nodsh"
17509         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
17510                 skip_env "ldiskfs only test"
17511         fi
17512
17513         local tgt
17514         local dev
17515         local out
17516         local uuid
17517         local num
17518         local gen
17519
17520         # check lr_reader on OST0000
17521         tgt=ost1
17522         dev=$(facet_device $tgt)
17523         out=$(do_facet $tgt $LR_READER $dev)
17524         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17525         echo "$out"
17526         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
17527         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
17528                 error "Invalid uuid returned by $LR_READER on target $tgt"
17529         echo -e "uuid returned by $LR_READER is '$uuid'\n"
17530
17531         # check lr_reader -c on MDT0000
17532         tgt=mds1
17533         dev=$(facet_device $tgt)
17534         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
17535                 skip "$LR_READER does not support additional options"
17536         fi
17537         out=$(do_facet $tgt $LR_READER -c $dev)
17538         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17539         echo "$out"
17540         num=$(echo "$out" | grep -c "mdtlov")
17541         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
17542                 error "Invalid number of mdtlov clients returned by $LR_READER"
17543         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
17544
17545         # check lr_reader -cr on MDT0000
17546         out=$(do_facet $tgt $LR_READER -cr $dev)
17547         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17548         echo "$out"
17549         echo "$out" | grep -q "^reply_data:$" ||
17550                 error "$LR_READER should have returned 'reply_data' section"
17551         num=$(echo "$out" | grep -c "client_generation")
17552         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
17553 }
17554 run_test 252 "check lr_reader tool"
17555
17556 test_253() {
17557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17558         remote_mds_nodsh && skip "remote MDS with nodsh"
17559         remote_mgs_nodsh && skip "remote MGS with nodsh"
17560
17561         local ostidx=0
17562         local rc=0
17563         local ost_name=$(ostname_from_index $ostidx)
17564
17565         # on the mdt's osc
17566         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
17567         do_facet $SINGLEMDS $LCTL get_param -n \
17568                 osp.$mdtosc_proc1.reserved_mb_high ||
17569                 skip  "remote MDS does not support reserved_mb_high"
17570
17571         rm -rf $DIR/$tdir
17572         wait_mds_ost_sync
17573         wait_delete_completed
17574         mkdir $DIR/$tdir
17575
17576         pool_add $TESTNAME || error "Pool creation failed"
17577         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
17578
17579         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
17580                 error "Setstripe failed"
17581
17582         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
17583
17584         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
17585                     grep "watermarks")
17586         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
17587
17588         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17589                         osp.$mdtosc_proc1.prealloc_status)
17590         echo "prealloc_status $oa_status"
17591
17592         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
17593                 error "File creation should fail"
17594
17595         #object allocation was stopped, but we still able to append files
17596         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
17597                 oflag=append || error "Append failed"
17598
17599         rm -f $DIR/$tdir/$tfile.0
17600
17601         # For this test, we want to delete the files we created to go out of
17602         # space but leave the watermark, so we remain nearly out of space
17603         ost_watermarks_enospc_delete_files $tfile $ostidx
17604
17605         wait_delete_completed
17606
17607         sleep_maxage
17608
17609         for i in $(seq 10 12); do
17610                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
17611                         2>/dev/null || error "File creation failed after rm"
17612         done
17613
17614         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17615                         osp.$mdtosc_proc1.prealloc_status)
17616         echo "prealloc_status $oa_status"
17617
17618         if (( oa_status != 0 )); then
17619                 error "Object allocation still disable after rm"
17620         fi
17621 }
17622 run_test 253 "Check object allocation limit"
17623
17624 test_254() {
17625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17626         remote_mds_nodsh && skip "remote MDS with nodsh"
17627         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17628                 skip "MDS does not support changelog_size"
17629
17630         local cl_user
17631         local MDT0=$(facet_svc $SINGLEMDS)
17632
17633         changelog_register || error "changelog_register failed"
17634
17635         changelog_clear 0 || error "changelog_clear failed"
17636
17637         local size1=$(do_facet $SINGLEMDS \
17638                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17639         echo "Changelog size $size1"
17640
17641         rm -rf $DIR/$tdir
17642         $LFS mkdir -i 0 $DIR/$tdir
17643         # change something
17644         mkdir -p $DIR/$tdir/pics/2008/zachy
17645         touch $DIR/$tdir/pics/2008/zachy/timestamp
17646         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17647         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17648         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17649         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17650         rm $DIR/$tdir/pics/desktop.jpg
17651
17652         local size2=$(do_facet $SINGLEMDS \
17653                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17654         echo "Changelog size after work $size2"
17655
17656         (( $size2 > $size1 )) ||
17657                 error "new Changelog size=$size2 less than old size=$size1"
17658 }
17659 run_test 254 "Check changelog size"
17660
17661 ladvise_no_type()
17662 {
17663         local type=$1
17664         local file=$2
17665
17666         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17667                 awk -F: '{print $2}' | grep $type > /dev/null
17668         if [ $? -ne 0 ]; then
17669                 return 0
17670         fi
17671         return 1
17672 }
17673
17674 ladvise_no_ioctl()
17675 {
17676         local file=$1
17677
17678         lfs ladvise -a willread $file > /dev/null 2>&1
17679         if [ $? -eq 0 ]; then
17680                 return 1
17681         fi
17682
17683         lfs ladvise -a willread $file 2>&1 |
17684                 grep "Inappropriate ioctl for device" > /dev/null
17685         if [ $? -eq 0 ]; then
17686                 return 0
17687         fi
17688         return 1
17689 }
17690
17691 percent() {
17692         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17693 }
17694
17695 # run a random read IO workload
17696 # usage: random_read_iops <filename> <filesize> <iosize>
17697 random_read_iops() {
17698         local file=$1
17699         local fsize=$2
17700         local iosize=${3:-4096}
17701
17702         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17703                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17704 }
17705
17706 drop_file_oss_cache() {
17707         local file="$1"
17708         local nodes="$2"
17709
17710         $LFS ladvise -a dontneed $file 2>/dev/null ||
17711                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17712 }
17713
17714 ladvise_willread_performance()
17715 {
17716         local repeat=10
17717         local average_origin=0
17718         local average_cache=0
17719         local average_ladvise=0
17720
17721         for ((i = 1; i <= $repeat; i++)); do
17722                 echo "Iter $i/$repeat: reading without willread hint"
17723                 cancel_lru_locks osc
17724                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17725                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17726                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17727                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17728
17729                 cancel_lru_locks osc
17730                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17731                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17732                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17733
17734                 cancel_lru_locks osc
17735                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17736                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17737                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17738                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17739                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17740         done
17741         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17742         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17743         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17744
17745         speedup_cache=$(percent $average_cache $average_origin)
17746         speedup_ladvise=$(percent $average_ladvise $average_origin)
17747
17748         echo "Average uncached read: $average_origin"
17749         echo "Average speedup with OSS cached read: " \
17750                 "$average_cache = +$speedup_cache%"
17751         echo "Average speedup with ladvise willread: " \
17752                 "$average_ladvise = +$speedup_ladvise%"
17753
17754         local lowest_speedup=20
17755         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17756                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17757                         "got $average_cache%. Skipping ladvise willread check."
17758                 return 0
17759         fi
17760
17761         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17762         # it is still good to run until then to exercise 'ladvise willread'
17763         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17764                 [ "$ost1_FSTYPE" = "zfs" ] &&
17765                 echo "osd-zfs does not support dontneed or drop_caches" &&
17766                 return 0
17767
17768         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17769         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17770                 error_not_in_vm "Speedup with willread is less than " \
17771                         "$lowest_speedup%, got $average_ladvise%"
17772 }
17773
17774 test_255a() {
17775         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17776                 skip "lustre < 2.8.54 does not support ladvise "
17777         remote_ost_nodsh && skip "remote OST with nodsh"
17778
17779         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17780
17781         ladvise_no_type willread $DIR/$tfile &&
17782                 skip "willread ladvise is not supported"
17783
17784         ladvise_no_ioctl $DIR/$tfile &&
17785                 skip "ladvise ioctl is not supported"
17786
17787         local size_mb=100
17788         local size=$((size_mb * 1048576))
17789         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17790                 error "dd to $DIR/$tfile failed"
17791
17792         lfs ladvise -a willread $DIR/$tfile ||
17793                 error "Ladvise failed with no range argument"
17794
17795         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17796                 error "Ladvise failed with no -l or -e argument"
17797
17798         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17799                 error "Ladvise failed with only -e argument"
17800
17801         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17802                 error "Ladvise failed with only -l argument"
17803
17804         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17805                 error "End offset should not be smaller than start offset"
17806
17807         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17808                 error "End offset should not be equal to start offset"
17809
17810         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17811                 error "Ladvise failed with overflowing -s argument"
17812
17813         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17814                 error "Ladvise failed with overflowing -e argument"
17815
17816         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17817                 error "Ladvise failed with overflowing -l argument"
17818
17819         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17820                 error "Ladvise succeeded with conflicting -l and -e arguments"
17821
17822         echo "Synchronous ladvise should wait"
17823         local delay=4
17824 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17825         do_nodes $(comma_list $(osts_nodes)) \
17826                 $LCTL set_param fail_val=$delay fail_loc=0x237
17827
17828         local start_ts=$SECONDS
17829         lfs ladvise -a willread $DIR/$tfile ||
17830                 error "Ladvise failed with no range argument"
17831         local end_ts=$SECONDS
17832         local inteval_ts=$((end_ts - start_ts))
17833
17834         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17835                 error "Synchronous advice didn't wait reply"
17836         fi
17837
17838         echo "Asynchronous ladvise shouldn't wait"
17839         local start_ts=$SECONDS
17840         lfs ladvise -a willread -b $DIR/$tfile ||
17841                 error "Ladvise failed with no range argument"
17842         local end_ts=$SECONDS
17843         local inteval_ts=$((end_ts - start_ts))
17844
17845         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17846                 error "Asynchronous advice blocked"
17847         fi
17848
17849         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
17850         ladvise_willread_performance
17851 }
17852 run_test 255a "check 'lfs ladvise -a willread'"
17853
17854 facet_meminfo() {
17855         local facet=$1
17856         local info=$2
17857
17858         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
17859 }
17860
17861 test_255b() {
17862         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17863                 skip "lustre < 2.8.54 does not support ladvise "
17864         remote_ost_nodsh && skip "remote OST with nodsh"
17865
17866         lfs setstripe -c 1 -i 0 $DIR/$tfile
17867
17868         ladvise_no_type dontneed $DIR/$tfile &&
17869                 skip "dontneed ladvise is not supported"
17870
17871         ladvise_no_ioctl $DIR/$tfile &&
17872                 skip "ladvise ioctl is not supported"
17873
17874         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17875                 [ "$ost1_FSTYPE" = "zfs" ] &&
17876                 skip "zfs-osd does not support 'ladvise dontneed'"
17877
17878         local size_mb=100
17879         local size=$((size_mb * 1048576))
17880         # In order to prevent disturbance of other processes, only check 3/4
17881         # of the memory usage
17882         local kibibytes=$((size_mb * 1024 * 3 / 4))
17883
17884         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17885                 error "dd to $DIR/$tfile failed"
17886
17887         #force write to complete before dropping OST cache & checking memory
17888         sync
17889
17890         local total=$(facet_meminfo ost1 MemTotal)
17891         echo "Total memory: $total KiB"
17892
17893         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
17894         local before_read=$(facet_meminfo ost1 Cached)
17895         echo "Cache used before read: $before_read KiB"
17896
17897         lfs ladvise -a willread $DIR/$tfile ||
17898                 error "Ladvise willread failed"
17899         local after_read=$(facet_meminfo ost1 Cached)
17900         echo "Cache used after read: $after_read KiB"
17901
17902         lfs ladvise -a dontneed $DIR/$tfile ||
17903                 error "Ladvise dontneed again failed"
17904         local no_read=$(facet_meminfo ost1 Cached)
17905         echo "Cache used after dontneed ladvise: $no_read KiB"
17906
17907         if [ $total -lt $((before_read + kibibytes)) ]; then
17908                 echo "Memory is too small, abort checking"
17909                 return 0
17910         fi
17911
17912         if [ $((before_read + kibibytes)) -gt $after_read ]; then
17913                 error "Ladvise willread should use more memory" \
17914                         "than $kibibytes KiB"
17915         fi
17916
17917         if [ $((no_read + kibibytes)) -gt $after_read ]; then
17918                 error "Ladvise dontneed should release more memory" \
17919                         "than $kibibytes KiB"
17920         fi
17921 }
17922 run_test 255b "check 'lfs ladvise -a dontneed'"
17923
17924 test_255c() {
17925         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
17926                 skip "lustre < 2.10.50 does not support lockahead"
17927
17928         local count
17929         local new_count
17930         local difference
17931         local i
17932         local rc
17933
17934         test_mkdir -p $DIR/$tdir
17935         $LFS setstripe -i 0 -c 1 $DIR/$tdir
17936
17937         #test 10 returns only success/failure
17938         i=10
17939         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17940         rc=$?
17941         if [ $rc -eq 255 ]; then
17942                 error "Ladvise test${i} failed, ${rc}"
17943         fi
17944
17945         #test 11 counts lock enqueue requests, all others count new locks
17946         i=11
17947         count=$(do_facet ost1 \
17948                 $LCTL get_param -n ost.OSS.ost.stats)
17949         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
17950
17951         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17952         rc=$?
17953         if [ $rc -eq 255 ]; then
17954                 error "Ladvise test${i} failed, ${rc}"
17955         fi
17956
17957         new_count=$(do_facet ost1 \
17958                 $LCTL get_param -n ost.OSS.ost.stats)
17959         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
17960                    awk '{ print $2 }')
17961
17962         difference="$((new_count - count))"
17963         if [ $difference -ne $rc ]; then
17964                 error "Ladvise test${i}, bad enqueue count, returned " \
17965                       "${rc}, actual ${difference}"
17966         fi
17967
17968         for i in $(seq 12 21); do
17969                 # If we do not do this, we run the risk of having too many
17970                 # locks and starting lock cancellation while we are checking
17971                 # lock counts.
17972                 cancel_lru_locks osc
17973
17974                 count=$($LCTL get_param -n \
17975                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17976
17977                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
17978                 rc=$?
17979                 if [ $rc -eq 255 ]; then
17980                         error "Ladvise test ${i} failed, ${rc}"
17981                 fi
17982
17983                 new_count=$($LCTL get_param -n \
17984                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17985                 difference="$((new_count - count))"
17986
17987                 # Test 15 output is divided by 100 to map down to valid return
17988                 if [ $i -eq 15 ]; then
17989                         rc="$((rc * 100))"
17990                 fi
17991
17992                 if [ $difference -ne $rc ]; then
17993                         error "Ladvise test ${i}, bad lock count, returned " \
17994                               "${rc}, actual ${difference}"
17995                 fi
17996         done
17997
17998         #test 22 returns only success/failure
17999         i=22
18000         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18001         rc=$?
18002         if [ $rc -eq 255 ]; then
18003                 error "Ladvise test${i} failed, ${rc}"
18004         fi
18005 }
18006 run_test 255c "suite of ladvise lockahead tests"
18007
18008 test_256() {
18009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18010         remote_mds_nodsh && skip "remote MDS with nodsh"
18011         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18012         changelog_users $SINGLEMDS | grep "^cl" &&
18013                 skip "active changelog user"
18014
18015         local cl_user
18016         local cat_sl
18017         local mdt_dev
18018
18019         mdt_dev=$(mdsdevname 1)
18020         echo $mdt_dev
18021
18022         changelog_register || error "changelog_register failed"
18023
18024         rm -rf $DIR/$tdir
18025         mkdir -p $DIR/$tdir
18026
18027         changelog_clear 0 || error "changelog_clear failed"
18028
18029         # change something
18030         touch $DIR/$tdir/{1..10}
18031
18032         # stop the MDT
18033         stop $SINGLEMDS || error "Fail to stop MDT"
18034
18035         # remount the MDT
18036
18037         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
18038
18039         #after mount new plainllog is used
18040         touch $DIR/$tdir/{11..19}
18041         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
18042         stack_trap "rm -f $tmpfile"
18043         cat_sl=$(do_facet $SINGLEMDS "sync; \
18044                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18045                  llog_reader $tmpfile | grep -c type=1064553b")
18046         do_facet $SINGLEMDS llog_reader $tmpfile
18047
18048         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
18049
18050         changelog_clear 0 || error "changelog_clear failed"
18051
18052         cat_sl=$(do_facet $SINGLEMDS "sync; \
18053                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18054                  llog_reader $tmpfile | grep -c type=1064553b")
18055
18056         if (( cat_sl == 2 )); then
18057                 error "Empty plain llog was not deleted from changelog catalog"
18058         elif (( cat_sl != 1 )); then
18059                 error "Active plain llog shouldn't be deleted from catalog"
18060         fi
18061 }
18062 run_test 256 "Check llog delete for empty and not full state"
18063
18064 test_257() {
18065         remote_mds_nodsh && skip "remote MDS with nodsh"
18066         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
18067                 skip "Need MDS version at least 2.8.55"
18068
18069         test_mkdir $DIR/$tdir
18070
18071         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
18072                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
18073         stat $DIR/$tdir
18074
18075 #define OBD_FAIL_MDS_XATTR_REP                  0x161
18076         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18077         local facet=mds$((mdtidx + 1))
18078         set_nodes_failloc $(facet_active_host $facet) 0x80000161
18079         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
18080
18081         stop $facet || error "stop MDS failed"
18082         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
18083                 error "start MDS fail"
18084         wait_recovery_complete $facet
18085 }
18086 run_test 257 "xattr locks are not lost"
18087
18088 # Verify we take the i_mutex when security requires it
18089 test_258a() {
18090 #define OBD_FAIL_IMUTEX_SEC 0x141c
18091         $LCTL set_param fail_loc=0x141c
18092         touch $DIR/$tfile
18093         chmod u+s $DIR/$tfile
18094         chmod a+rwx $DIR/$tfile
18095         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18096         RC=$?
18097         if [ $RC -ne 0 ]; then
18098                 error "error, failed to take i_mutex, rc=$?"
18099         fi
18100         rm -f $DIR/$tfile
18101 }
18102 run_test 258a "verify i_mutex security behavior when suid attributes is set"
18103
18104 # Verify we do NOT take the i_mutex in the normal case
18105 test_258b() {
18106 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
18107         $LCTL set_param fail_loc=0x141d
18108         touch $DIR/$tfile
18109         chmod a+rwx $DIR
18110         chmod a+rw $DIR/$tfile
18111         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18112         RC=$?
18113         if [ $RC -ne 0 ]; then
18114                 error "error, took i_mutex unnecessarily, rc=$?"
18115         fi
18116         rm -f $DIR/$tfile
18117
18118 }
18119 run_test 258b "verify i_mutex security behavior"
18120
18121 test_259() {
18122         local file=$DIR/$tfile
18123         local before
18124         local after
18125
18126         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18127
18128         stack_trap "rm -f $file" EXIT
18129
18130         wait_delete_completed
18131         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18132         echo "before: $before"
18133
18134         $LFS setstripe -i 0 -c 1 $file
18135         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
18136         sync_all_data
18137         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18138         echo "after write: $after"
18139
18140 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
18141         do_facet ost1 $LCTL set_param fail_loc=0x2301
18142         $TRUNCATE $file 0
18143         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18144         echo "after truncate: $after"
18145
18146         stop ost1
18147         do_facet ost1 $LCTL set_param fail_loc=0
18148         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18149         sleep 2
18150         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18151         echo "after restart: $after"
18152         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
18153                 error "missing truncate?"
18154
18155         return 0
18156 }
18157 run_test 259 "crash at delayed truncate"
18158
18159 test_260() {
18160 #define OBD_FAIL_MDC_CLOSE               0x806
18161         $LCTL set_param fail_loc=0x80000806
18162         touch $DIR/$tfile
18163
18164 }
18165 run_test 260 "Check mdc_close fail"
18166
18167 ### Data-on-MDT sanity tests ###
18168 test_270a() {
18169         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18170                 skip "Need MDS version at least 2.10.55 for DoM"
18171
18172         # create DoM file
18173         local dom=$DIR/$tdir/dom_file
18174         local tmp=$DIR/$tdir/tmp_file
18175
18176         mkdir -p $DIR/$tdir
18177
18178         # basic checks for DoM component creation
18179         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
18180                 error "Can set MDT layout to non-first entry"
18181
18182         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
18183                 error "Can define multiple entries as MDT layout"
18184
18185         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
18186
18187         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
18188         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
18189         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
18190
18191         local mdtidx=$($LFS getstripe -m $dom)
18192         local mdtname=MDT$(printf %04x $mdtidx)
18193         local facet=mds$((mdtidx + 1))
18194         local space_check=1
18195
18196         # Skip free space checks with ZFS
18197         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
18198
18199         # write
18200         sync
18201         local size_tmp=$((65536 * 3))
18202         local mdtfree1=$(do_facet $facet \
18203                          lctl get_param -n osd*.*$mdtname.kbytesfree)
18204
18205         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18206         # check also direct IO along write
18207         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
18208         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18209         sync
18210         cmp $tmp $dom || error "file data is different"
18211         [ $(stat -c%s $dom) == $size_tmp ] ||
18212                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18213         if [ $space_check == 1 ]; then
18214                 local mdtfree2=$(do_facet $facet \
18215                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
18216
18217                 # increase in usage from by $size_tmp
18218                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18219                         error "MDT free space wrong after write: " \
18220                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18221         fi
18222
18223         # truncate
18224         local size_dom=10000
18225
18226         $TRUNCATE $dom $size_dom
18227         [ $(stat -c%s $dom) == $size_dom ] ||
18228                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
18229         if [ $space_check == 1 ]; then
18230                 mdtfree1=$(do_facet $facet \
18231                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18232                 # decrease in usage from $size_tmp to new $size_dom
18233                 [ $(($mdtfree1 - $mdtfree2)) -ge \
18234                   $(((size_tmp - size_dom) / 1024)) ] ||
18235                         error "MDT free space is wrong after truncate: " \
18236                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
18237         fi
18238
18239         # append
18240         cat $tmp >> $dom
18241         sync
18242         size_dom=$((size_dom + size_tmp))
18243         [ $(stat -c%s $dom) == $size_dom ] ||
18244                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
18245         if [ $space_check == 1 ]; then
18246                 mdtfree2=$(do_facet $facet \
18247                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18248                 # increase in usage by $size_tmp from previous
18249                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18250                         error "MDT free space is wrong after append: " \
18251                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18252         fi
18253
18254         # delete
18255         rm $dom
18256         if [ $space_check == 1 ]; then
18257                 mdtfree1=$(do_facet $facet \
18258                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18259                 # decrease in usage by $size_dom from previous
18260                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
18261                         error "MDT free space is wrong after removal: " \
18262                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
18263         fi
18264
18265         # combined striping
18266         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
18267                 error "Can't create DoM + OST striping"
18268
18269         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
18270         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18271         # check also direct IO along write
18272         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18273         sync
18274         cmp $tmp $dom || error "file data is different"
18275         [ $(stat -c%s $dom) == $size_tmp ] ||
18276                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18277         rm $dom $tmp
18278
18279         return 0
18280 }
18281 run_test 270a "DoM: basic functionality tests"
18282
18283 test_270b() {
18284         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18285                 skip "Need MDS version at least 2.10.55"
18286
18287         local dom=$DIR/$tdir/dom_file
18288         local max_size=1048576
18289
18290         mkdir -p $DIR/$tdir
18291         $LFS setstripe -E $max_size -L mdt $dom
18292
18293         # truncate over the limit
18294         $TRUNCATE $dom $(($max_size + 1)) &&
18295                 error "successful truncate over the maximum size"
18296         # write over the limit
18297         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
18298                 error "successful write over the maximum size"
18299         # append over the limit
18300         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
18301         echo "12345" >> $dom && error "successful append over the maximum size"
18302         rm $dom
18303
18304         return 0
18305 }
18306 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
18307
18308 test_270c() {
18309         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18310                 skip "Need MDS version at least 2.10.55"
18311
18312         mkdir -p $DIR/$tdir
18313         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18314
18315         # check files inherit DoM EA
18316         touch $DIR/$tdir/first
18317         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
18318                 error "bad pattern"
18319         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
18320                 error "bad stripe count"
18321         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
18322                 error "bad stripe size"
18323
18324         # check directory inherits DoM EA and uses it as default
18325         mkdir $DIR/$tdir/subdir
18326         touch $DIR/$tdir/subdir/second
18327         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
18328                 error "bad pattern in sub-directory"
18329         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
18330                 error "bad stripe count in sub-directory"
18331         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
18332                 error "bad stripe size in sub-directory"
18333         return 0
18334 }
18335 run_test 270c "DoM: DoM EA inheritance tests"
18336
18337 test_270d() {
18338         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18339                 skip "Need MDS version at least 2.10.55"
18340
18341         mkdir -p $DIR/$tdir
18342         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18343
18344         # inherit default DoM striping
18345         mkdir $DIR/$tdir/subdir
18346         touch $DIR/$tdir/subdir/f1
18347
18348         # change default directory striping
18349         $LFS setstripe -c 1 $DIR/$tdir/subdir
18350         touch $DIR/$tdir/subdir/f2
18351         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
18352                 error "wrong default striping in file 2"
18353         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
18354                 error "bad pattern in file 2"
18355         return 0
18356 }
18357 run_test 270d "DoM: change striping from DoM to RAID0"
18358
18359 test_270e() {
18360         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18361                 skip "Need MDS version at least 2.10.55"
18362
18363         mkdir -p $DIR/$tdir/dom
18364         mkdir -p $DIR/$tdir/norm
18365         DOMFILES=20
18366         NORMFILES=10
18367         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
18368         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
18369
18370         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
18371         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
18372
18373         # find DoM files by layout
18374         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
18375         [ $NUM -eq  $DOMFILES ] ||
18376                 error "lfs find -L: found $NUM, expected $DOMFILES"
18377         echo "Test 1: lfs find 20 DOM files by layout: OK"
18378
18379         # there should be 1 dir with default DOM striping
18380         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
18381         [ $NUM -eq  1 ] ||
18382                 error "lfs find -L: found $NUM, expected 1 dir"
18383         echo "Test 2: lfs find 1 DOM dir by layout: OK"
18384
18385         # find DoM files by stripe size
18386         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
18387         [ $NUM -eq  $DOMFILES ] ||
18388                 error "lfs find -S: found $NUM, expected $DOMFILES"
18389         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
18390
18391         # find files by stripe offset except DoM files
18392         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
18393         [ $NUM -eq  $NORMFILES ] ||
18394                 error "lfs find -i: found $NUM, expected $NORMFILES"
18395         echo "Test 5: lfs find no DOM files by stripe index: OK"
18396         return 0
18397 }
18398 run_test 270e "DoM: lfs find with DoM files test"
18399
18400 test_270f() {
18401         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18402                 skip "Need MDS version at least 2.10.55"
18403
18404         local mdtname=${FSNAME}-MDT0000-mdtlov
18405         local dom=$DIR/$tdir/dom_file
18406         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
18407                                                 lod.$mdtname.dom_stripesize)
18408         local dom_limit=131072
18409
18410         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
18411         local dom_current=$(do_facet mds1 $LCTL get_param -n \
18412                                                 lod.$mdtname.dom_stripesize)
18413         [ ${dom_limit} -eq ${dom_current} ] ||
18414                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
18415
18416         $LFS mkdir -i 0 -c 1 $DIR/$tdir
18417         $LFS setstripe -d $DIR/$tdir
18418         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
18419                 error "Can't set directory default striping"
18420
18421         # exceed maximum stripe size
18422         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18423                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
18424         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
18425                 error "Able to create DoM component size more than LOD limit"
18426
18427         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
18428         dom_current=$(do_facet mds1 $LCTL get_param -n \
18429                                                 lod.$mdtname.dom_stripesize)
18430         [ 0 -eq ${dom_current} ] ||
18431                 error "Can't set zero DoM stripe limit"
18432         rm $dom
18433
18434         # attempt to create DoM file on server with disabled DoM should
18435         # remove DoM entry from layout and be succeed
18436         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
18437                 error "Can't create DoM file (DoM is disabled)"
18438         [ $($LFS getstripe -L $dom) == "mdt" ] &&
18439                 error "File has DoM component while DoM is disabled"
18440         rm $dom
18441
18442         # attempt to create DoM file with only DoM stripe should return error
18443         $LFS setstripe -E $dom_limit -L mdt $dom &&
18444                 error "Able to create DoM-only file while DoM is disabled"
18445
18446         # too low values to be aligned with smallest stripe size 64K
18447         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
18448         dom_current=$(do_facet mds1 $LCTL get_param -n \
18449                                                 lod.$mdtname.dom_stripesize)
18450         [ 30000 -eq ${dom_current} ] &&
18451                 error "Can set too small DoM stripe limit"
18452
18453         # 64K is a minimal stripe size in Lustre, expect limit of that size
18454         [ 65536 -eq ${dom_current} ] ||
18455                 error "Limit is not set to 64K but ${dom_current}"
18456
18457         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
18458         dom_current=$(do_facet mds1 $LCTL get_param -n \
18459                                                 lod.$mdtname.dom_stripesize)
18460         echo $dom_current
18461         [ 2147483648 -eq ${dom_current} ] &&
18462                 error "Can set too large DoM stripe limit"
18463
18464         do_facet mds1 $LCTL set_param -n \
18465                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
18466         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18467                 error "Can't create DoM component size after limit change"
18468         do_facet mds1 $LCTL set_param -n \
18469                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
18470         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
18471                 error "Can't create DoM file after limit decrease"
18472         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
18473                 error "Can create big DoM component after limit decrease"
18474         touch ${dom}_def ||
18475                 error "Can't create file with old default layout"
18476
18477         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
18478         return 0
18479 }
18480 run_test 270f "DoM: maximum DoM stripe size checks"
18481
18482 test_271a() {
18483         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18484                 skip "Need MDS version at least 2.10.55"
18485
18486         local dom=$DIR/$tdir/dom
18487
18488         mkdir -p $DIR/$tdir
18489
18490         $LFS setstripe -E 1024K -L mdt $dom
18491
18492         lctl set_param -n mdc.*.stats=clear
18493         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18494         cat $dom > /dev/null
18495         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
18496         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
18497         ls $dom
18498         rm -f $dom
18499 }
18500 run_test 271a "DoM: data is cached for read after write"
18501
18502 test_271b() {
18503         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18504                 skip "Need MDS version at least 2.10.55"
18505
18506         local dom=$DIR/$tdir/dom
18507
18508         mkdir -p $DIR/$tdir
18509
18510         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18511
18512         lctl set_param -n mdc.*.stats=clear
18513         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18514         cancel_lru_locks mdc
18515         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
18516         # second stat to check size is cached on client
18517         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
18518         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18519         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
18520         rm -f $dom
18521 }
18522 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
18523
18524 test_271ba() {
18525         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18526                 skip "Need MDS version at least 2.10.55"
18527
18528         local dom=$DIR/$tdir/dom
18529
18530         mkdir -p $DIR/$tdir
18531
18532         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18533
18534         lctl set_param -n mdc.*.stats=clear
18535         lctl set_param -n osc.*.stats=clear
18536         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
18537         cancel_lru_locks mdc
18538         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18539         # second stat to check size is cached on client
18540         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18541         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18542         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
18543         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
18544         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
18545         rm -f $dom
18546 }
18547 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
18548
18549
18550 get_mdc_stats() {
18551         local mdtidx=$1
18552         local param=$2
18553         local mdt=MDT$(printf %04x $mdtidx)
18554
18555         if [ -z $param ]; then
18556                 lctl get_param -n mdc.*$mdt*.stats
18557         else
18558                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
18559         fi
18560 }
18561
18562 test_271c() {
18563         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18564                 skip "Need MDS version at least 2.10.55"
18565
18566         local dom=$DIR/$tdir/dom
18567
18568         mkdir -p $DIR/$tdir
18569
18570         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18571
18572         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18573         local facet=mds$((mdtidx + 1))
18574
18575         cancel_lru_locks mdc
18576         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
18577         createmany -o $dom 1000
18578         lctl set_param -n mdc.*.stats=clear
18579         smalliomany -w $dom 1000 200
18580         get_mdc_stats $mdtidx
18581         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18582         # Each file has 1 open, 1 IO enqueues, total 2000
18583         # but now we have also +1 getxattr for security.capability, total 3000
18584         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
18585         unlinkmany $dom 1000
18586
18587         cancel_lru_locks mdc
18588         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
18589         createmany -o $dom 1000
18590         lctl set_param -n mdc.*.stats=clear
18591         smalliomany -w $dom 1000 200
18592         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18593         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
18594         # for OPEN and IO lock.
18595         [ $((enq - enq_2)) -ge 1000 ] ||
18596                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
18597         unlinkmany $dom 1000
18598         return 0
18599 }
18600 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
18601
18602 cleanup_271def_tests() {
18603         trap 0
18604         rm -f $1
18605 }
18606
18607 test_271d() {
18608         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18609                 skip "Need MDS version at least 2.10.57"
18610
18611         local dom=$DIR/$tdir/dom
18612         local tmp=$TMP/$tfile
18613         trap "cleanup_271def_tests $tmp" EXIT
18614
18615         mkdir -p $DIR/$tdir
18616
18617         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18618
18619         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18620
18621         cancel_lru_locks mdc
18622         dd if=/dev/urandom of=$tmp bs=1000 count=1
18623         dd if=$tmp of=$dom bs=1000 count=1
18624         cancel_lru_locks mdc
18625
18626         cat /etc/hosts >> $tmp
18627         lctl set_param -n mdc.*.stats=clear
18628
18629         # append data to the same file it should update local page
18630         echo "Append to the same page"
18631         cat /etc/hosts >> $dom
18632         local num=$(get_mdc_stats $mdtidx ost_read)
18633         local ra=$(get_mdc_stats $mdtidx req_active)
18634         local rw=$(get_mdc_stats $mdtidx req_waittime)
18635
18636         [ -z $num ] || error "$num READ RPC occured"
18637         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18638         echo "... DONE"
18639
18640         # compare content
18641         cmp $tmp $dom || error "file miscompare"
18642
18643         cancel_lru_locks mdc
18644         lctl set_param -n mdc.*.stats=clear
18645
18646         echo "Open and read file"
18647         cat $dom > /dev/null
18648         local num=$(get_mdc_stats $mdtidx ost_read)
18649         local ra=$(get_mdc_stats $mdtidx req_active)
18650         local rw=$(get_mdc_stats $mdtidx req_waittime)
18651
18652         [ -z $num ] || error "$num READ RPC occured"
18653         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18654         echo "... DONE"
18655
18656         # compare content
18657         cmp $tmp $dom || error "file miscompare"
18658
18659         return 0
18660 }
18661 run_test 271d "DoM: read on open (1K file in reply buffer)"
18662
18663 test_271f() {
18664         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18665                 skip "Need MDS version at least 2.10.57"
18666
18667         local dom=$DIR/$tdir/dom
18668         local tmp=$TMP/$tfile
18669         trap "cleanup_271def_tests $tmp" EXIT
18670
18671         mkdir -p $DIR/$tdir
18672
18673         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18674
18675         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18676
18677         cancel_lru_locks mdc
18678         dd if=/dev/urandom of=$tmp bs=265000 count=1
18679         dd if=$tmp of=$dom bs=265000 count=1
18680         cancel_lru_locks mdc
18681         cat /etc/hosts >> $tmp
18682         lctl set_param -n mdc.*.stats=clear
18683
18684         echo "Append to the same page"
18685         cat /etc/hosts >> $dom
18686         local num=$(get_mdc_stats $mdtidx ost_read)
18687         local ra=$(get_mdc_stats $mdtidx req_active)
18688         local rw=$(get_mdc_stats $mdtidx req_waittime)
18689
18690         [ -z $num ] || error "$num READ RPC occured"
18691         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18692         echo "... DONE"
18693
18694         # compare content
18695         cmp $tmp $dom || error "file miscompare"
18696
18697         cancel_lru_locks mdc
18698         lctl set_param -n mdc.*.stats=clear
18699
18700         echo "Open and read file"
18701         cat $dom > /dev/null
18702         local num=$(get_mdc_stats $mdtidx ost_read)
18703         local ra=$(get_mdc_stats $mdtidx req_active)
18704         local rw=$(get_mdc_stats $mdtidx req_waittime)
18705
18706         [ -z $num ] && num=0
18707         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18708         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18709         echo "... DONE"
18710
18711         # compare content
18712         cmp $tmp $dom || error "file miscompare"
18713
18714         return 0
18715 }
18716 run_test 271f "DoM: read on open (200K file and read tail)"
18717
18718 test_271g() {
18719         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18720                 skip "Skipping due to old client or server version"
18721
18722         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18723         # to get layout
18724         $CHECKSTAT -t file $DIR1/$tfile
18725
18726         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18727         MULTIOP_PID=$!
18728         sleep 1
18729         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18730         $LCTL set_param fail_loc=0x80000314
18731         rm $DIR1/$tfile || error "Unlink fails"
18732         RC=$?
18733         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18734         [ $RC -eq 0 ] || error "Failed write to stale object"
18735 }
18736 run_test 271g "Discard DoM data vs client flush race"
18737
18738 test_272a() {
18739         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18740                 skip "Need MDS version at least 2.11.50"
18741
18742         local dom=$DIR/$tdir/dom
18743         mkdir -p $DIR/$tdir
18744
18745         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18746         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18747                 error "failed to write data into $dom"
18748         local old_md5=$(md5sum $dom)
18749
18750         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18751                 error "failed to migrate to the same DoM component"
18752
18753         local new_md5=$(md5sum $dom)
18754
18755         [ "$old_md5" == "$new_md5" ] ||
18756                 error "md5sum differ: $old_md5, $new_md5"
18757
18758         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18759                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18760 }
18761 run_test 272a "DoM migration: new layout with the same DOM component"
18762
18763 test_272b() {
18764         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18765                 skip "Need MDS version at least 2.11.50"
18766
18767         local dom=$DIR/$tdir/dom
18768         mkdir -p $DIR/$tdir
18769         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18770
18771         local mdtidx=$($LFS getstripe -m $dom)
18772         local mdtname=MDT$(printf %04x $mdtidx)
18773         local facet=mds$((mdtidx + 1))
18774
18775         local mdtfree1=$(do_facet $facet \
18776                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18777         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18778                 error "failed to write data into $dom"
18779         local old_md5=$(md5sum $dom)
18780         cancel_lru_locks mdc
18781         local mdtfree1=$(do_facet $facet \
18782                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18783
18784         $LFS migrate -c2 $dom ||
18785                 error "failed to migrate to the new composite layout"
18786         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18787                 error "MDT stripe was not removed"
18788
18789         cancel_lru_locks mdc
18790         local new_md5=$(md5sum $dom)
18791         [ "$old_md5" == "$new_md5" ] ||
18792                 error "$old_md5 != $new_md5"
18793
18794         # Skip free space checks with ZFS
18795         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18796                 local mdtfree2=$(do_facet $facet \
18797                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18798                 [ $mdtfree2 -gt $mdtfree1 ] ||
18799                         error "MDT space is not freed after migration"
18800         fi
18801         return 0
18802 }
18803 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18804
18805 test_272c() {
18806         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18807                 skip "Need MDS version at least 2.11.50"
18808
18809         local dom=$DIR/$tdir/$tfile
18810         mkdir -p $DIR/$tdir
18811         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18812
18813         local mdtidx=$($LFS getstripe -m $dom)
18814         local mdtname=MDT$(printf %04x $mdtidx)
18815         local facet=mds$((mdtidx + 1))
18816
18817         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18818                 error "failed to write data into $dom"
18819         local old_md5=$(md5sum $dom)
18820         cancel_lru_locks mdc
18821         local mdtfree1=$(do_facet $facet \
18822                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18823
18824         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18825                 error "failed to migrate to the new composite layout"
18826         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18827                 error "MDT stripe was not removed"
18828
18829         cancel_lru_locks mdc
18830         local new_md5=$(md5sum $dom)
18831         [ "$old_md5" == "$new_md5" ] ||
18832                 error "$old_md5 != $new_md5"
18833
18834         # Skip free space checks with ZFS
18835         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18836                 local mdtfree2=$(do_facet $facet \
18837                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18838                 [ $mdtfree2 -gt $mdtfree1 ] ||
18839                         error "MDS space is not freed after migration"
18840         fi
18841         return 0
18842 }
18843 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18844
18845 test_272d() {
18846         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18847                 skip "Need MDS version at least 2.12.55"
18848
18849         local dom=$DIR/$tdir/$tfile
18850         mkdir -p $DIR/$tdir
18851         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18852
18853         local mdtidx=$($LFS getstripe -m $dom)
18854         local mdtname=MDT$(printf %04x $mdtidx)
18855         local facet=mds$((mdtidx + 1))
18856
18857         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18858                 error "failed to write data into $dom"
18859         local old_md5=$(md5sum $dom)
18860         cancel_lru_locks mdc
18861         local mdtfree1=$(do_facet $facet \
18862                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18863
18864         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
18865                 error "failed mirroring to the new composite layout"
18866         $LFS mirror resync $dom ||
18867                 error "failed mirror resync"
18868         $LFS mirror split --mirror-id 1 -d $dom ||
18869                 error "failed mirror split"
18870
18871         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18872                 error "MDT stripe was not removed"
18873
18874         cancel_lru_locks mdc
18875         local new_md5=$(md5sum $dom)
18876         [ "$old_md5" == "$new_md5" ] ||
18877                 error "$old_md5 != $new_md5"
18878
18879         # Skip free space checks with ZFS
18880         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18881                 local mdtfree2=$(do_facet $facet \
18882                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18883                 [ $mdtfree2 -gt $mdtfree1 ] ||
18884                         error "MDS space is not freed after DOM mirror deletion"
18885         fi
18886         return 0
18887 }
18888 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
18889
18890 test_272e() {
18891         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18892                 skip "Need MDS version at least 2.12.55"
18893
18894         local dom=$DIR/$tdir/$tfile
18895         mkdir -p $DIR/$tdir
18896         $LFS setstripe -c 2 $dom
18897
18898         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
18899                 error "failed to write data into $dom"
18900         local old_md5=$(md5sum $dom)
18901         cancel_lru_locks mdc
18902
18903         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
18904                 error "failed mirroring to the DOM layout"
18905         $LFS mirror resync $dom ||
18906                 error "failed mirror resync"
18907         $LFS mirror split --mirror-id 1 -d $dom ||
18908                 error "failed mirror split"
18909
18910         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18911                 error "MDT stripe was not removed"
18912
18913         cancel_lru_locks mdc
18914         local new_md5=$(md5sum $dom)
18915         [ "$old_md5" == "$new_md5" ] ||
18916                 error "$old_md5 != $new_md5"
18917
18918         return 0
18919 }
18920 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
18921
18922 test_272f() {
18923         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18924                 skip "Need MDS version at least 2.12.55"
18925
18926         local dom=$DIR/$tdir/$tfile
18927         mkdir -p $DIR/$tdir
18928         $LFS setstripe -c 2 $dom
18929
18930         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
18931                 error "failed to write data into $dom"
18932         local old_md5=$(md5sum $dom)
18933         cancel_lru_locks mdc
18934
18935         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
18936                 error "failed migrating to the DOM file"
18937
18938         cancel_lru_locks mdc
18939         local new_md5=$(md5sum $dom)
18940         [ "$old_md5" != "$new_md5" ] &&
18941                 error "$old_md5 != $new_md5"
18942
18943         return 0
18944 }
18945 run_test 272f "DoM migration: OST-striped file to DOM file"
18946
18947 test_273a() {
18948         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18949                 skip "Need MDS version at least 2.11.50"
18950
18951         # Layout swap cannot be done if either file has DOM component,
18952         # this will never be supported, migration should be used instead
18953
18954         local dom=$DIR/$tdir/$tfile
18955         mkdir -p $DIR/$tdir
18956
18957         $LFS setstripe -c2 ${dom}_plain
18958         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
18959         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
18960                 error "can swap layout with DoM component"
18961         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
18962                 error "can swap layout with DoM component"
18963
18964         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
18965         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
18966                 error "can swap layout with DoM component"
18967         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
18968                 error "can swap layout with DoM component"
18969         return 0
18970 }
18971 run_test 273a "DoM: layout swapping should fail with DOM"
18972
18973 test_275() {
18974         remote_ost_nodsh && skip "remote OST with nodsh"
18975         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
18976                 skip "Need OST version >= 2.10.57"
18977
18978         local file=$DIR/$tfile
18979         local oss
18980
18981         oss=$(comma_list $(osts_nodes))
18982
18983         dd if=/dev/urandom of=$file bs=1M count=2 ||
18984                 error "failed to create a file"
18985         cancel_lru_locks osc
18986
18987         #lock 1
18988         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18989                 error "failed to read a file"
18990
18991 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
18992         $LCTL set_param fail_loc=0x8000031f
18993
18994         cancel_lru_locks osc &
18995         sleep 1
18996
18997 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
18998         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
18999         #IO takes another lock, but matches the PENDING one
19000         #and places it to the IO RPC
19001         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19002                 error "failed to read a file with PENDING lock"
19003 }
19004 run_test 275 "Read on a canceled duplicate lock"
19005
19006 test_276() {
19007         remote_ost_nodsh && skip "remote OST with nodsh"
19008         local pid
19009
19010         do_facet ost1 "(while true; do \
19011                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
19012                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
19013         pid=$!
19014
19015         for LOOP in $(seq 20); do
19016                 stop ost1
19017                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
19018         done
19019         kill -9 $pid
19020         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
19021                 rm $TMP/sanity_276_pid"
19022 }
19023 run_test 276 "Race between mount and obd_statfs"
19024
19025 test_277() {
19026         $LCTL set_param ldlm.namespaces.*.lru_size=0
19027         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
19028         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19029                         grep ^used_mb | awk '{print $2}')
19030         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
19031         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
19032                 oflag=direct conv=notrunc
19033         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19034                         grep ^used_mb | awk '{print $2}')
19035         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
19036 }
19037 run_test 277 "Direct IO shall drop page cache"
19038
19039 test_278() {
19040         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19041         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19042         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
19043                 skip "needs the same host for mdt1 mdt2" && return
19044
19045         local pid1
19046         local pid2
19047
19048 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
19049         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
19050         stop mds2 &
19051         pid2=$!
19052
19053         stop mds1
19054
19055         echo "Starting MDTs"
19056         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
19057         wait $pid2
19058 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
19059 #will return NULL
19060         do_facet mds2 $LCTL set_param fail_loc=0
19061
19062         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
19063         wait_recovery_complete mds2
19064 }
19065 run_test 278 "Race starting MDS between MDTs stop/start"
19066
19067 cleanup_test_300() {
19068         trap 0
19069         umask $SAVE_UMASK
19070 }
19071 test_striped_dir() {
19072         local mdt_index=$1
19073         local stripe_count
19074         local stripe_index
19075
19076         mkdir -p $DIR/$tdir
19077
19078         SAVE_UMASK=$(umask)
19079         trap cleanup_test_300 RETURN EXIT
19080
19081         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
19082                                                 $DIR/$tdir/striped_dir ||
19083                 error "set striped dir error"
19084
19085         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
19086         [ "$mode" = "755" ] || error "expect 755 got $mode"
19087
19088         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
19089                 error "getdirstripe failed"
19090         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
19091         if [ "$stripe_count" != "2" ]; then
19092                 error "1:stripe_count is $stripe_count, expect 2"
19093         fi
19094         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
19095         if [ "$stripe_count" != "2" ]; then
19096                 error "2:stripe_count is $stripe_count, expect 2"
19097         fi
19098
19099         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
19100         if [ "$stripe_index" != "$mdt_index" ]; then
19101                 error "stripe_index is $stripe_index, expect $mdt_index"
19102         fi
19103
19104         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19105                 error "nlink error after create striped dir"
19106
19107         mkdir $DIR/$tdir/striped_dir/a
19108         mkdir $DIR/$tdir/striped_dir/b
19109
19110         stat $DIR/$tdir/striped_dir/a ||
19111                 error "create dir under striped dir failed"
19112         stat $DIR/$tdir/striped_dir/b ||
19113                 error "create dir under striped dir failed"
19114
19115         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
19116                 error "nlink error after mkdir"
19117
19118         rmdir $DIR/$tdir/striped_dir/a
19119         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
19120                 error "nlink error after rmdir"
19121
19122         rmdir $DIR/$tdir/striped_dir/b
19123         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19124                 error "nlink error after rmdir"
19125
19126         chattr +i $DIR/$tdir/striped_dir
19127         createmany -o $DIR/$tdir/striped_dir/f 10 &&
19128                 error "immutable flags not working under striped dir!"
19129         chattr -i $DIR/$tdir/striped_dir
19130
19131         rmdir $DIR/$tdir/striped_dir ||
19132                 error "rmdir striped dir error"
19133
19134         cleanup_test_300
19135
19136         true
19137 }
19138
19139 test_300a() {
19140         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19141                 skip "skipped for lustre < 2.7.0"
19142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19143         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19144
19145         test_striped_dir 0 || error "failed on striped dir on MDT0"
19146         test_striped_dir 1 || error "failed on striped dir on MDT0"
19147 }
19148 run_test 300a "basic striped dir sanity test"
19149
19150 test_300b() {
19151         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19152                 skip "skipped for lustre < 2.7.0"
19153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19154         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19155
19156         local i
19157         local mtime1
19158         local mtime2
19159         local mtime3
19160
19161         test_mkdir $DIR/$tdir || error "mkdir fail"
19162         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19163                 error "set striped dir error"
19164         for i in {0..9}; do
19165                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
19166                 sleep 1
19167                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
19168                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
19169                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
19170                 sleep 1
19171                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
19172                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
19173                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
19174         done
19175         true
19176 }
19177 run_test 300b "check ctime/mtime for striped dir"
19178
19179 test_300c() {
19180         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19181                 skip "skipped for lustre < 2.7.0"
19182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19183         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19184
19185         local file_count
19186
19187         mkdir -p $DIR/$tdir
19188         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
19189                 error "set striped dir error"
19190
19191         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
19192                 error "chown striped dir failed"
19193
19194         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
19195                 error "create 5k files failed"
19196
19197         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
19198
19199         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
19200
19201         rm -rf $DIR/$tdir
19202 }
19203 run_test 300c "chown && check ls under striped directory"
19204
19205 test_300d() {
19206         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19207                 skip "skipped for lustre < 2.7.0"
19208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19209         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19210
19211         local stripe_count
19212         local file
19213
19214         mkdir -p $DIR/$tdir
19215         $LFS setstripe -c 2 $DIR/$tdir
19216
19217         #local striped directory
19218         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19219                 error "set striped dir error"
19220         createmany -o $DIR/$tdir/striped_dir/f 10 ||
19221                 error "create 10 files failed"
19222
19223         #remote striped directory
19224         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
19225                 error "set striped dir error"
19226         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
19227                 error "create 10 files failed"
19228
19229         for file in $(find $DIR/$tdir); do
19230                 stripe_count=$($LFS getstripe -c $file)
19231                 [ $stripe_count -eq 2 ] ||
19232                         error "wrong stripe $stripe_count for $file"
19233         done
19234
19235         rm -rf $DIR/$tdir
19236 }
19237 run_test 300d "check default stripe under striped directory"
19238
19239 test_300e() {
19240         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19241                 skip "Need MDS version at least 2.7.55"
19242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19243         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19244
19245         local stripe_count
19246         local file
19247
19248         mkdir -p $DIR/$tdir
19249
19250         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19251                 error "set striped dir error"
19252
19253         touch $DIR/$tdir/striped_dir/a
19254         touch $DIR/$tdir/striped_dir/b
19255         touch $DIR/$tdir/striped_dir/c
19256
19257         mkdir $DIR/$tdir/striped_dir/dir_a
19258         mkdir $DIR/$tdir/striped_dir/dir_b
19259         mkdir $DIR/$tdir/striped_dir/dir_c
19260
19261         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
19262                 error "set striped adir under striped dir error"
19263
19264         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
19265                 error "set striped bdir under striped dir error"
19266
19267         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
19268                 error "set striped cdir under striped dir error"
19269
19270         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
19271                 error "rename dir under striped dir fails"
19272
19273         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
19274                 error "rename dir under different stripes fails"
19275
19276         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
19277                 error "rename file under striped dir should succeed"
19278
19279         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
19280                 error "rename dir under striped dir should succeed"
19281
19282         rm -rf $DIR/$tdir
19283 }
19284 run_test 300e "check rename under striped directory"
19285
19286 test_300f() {
19287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19288         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19289         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19290                 skip "Need MDS version at least 2.7.55"
19291
19292         local stripe_count
19293         local file
19294
19295         rm -rf $DIR/$tdir
19296         mkdir -p $DIR/$tdir
19297
19298         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19299                 error "set striped dir error"
19300
19301         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
19302                 error "set striped dir error"
19303
19304         touch $DIR/$tdir/striped_dir/a
19305         mkdir $DIR/$tdir/striped_dir/dir_a
19306         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
19307                 error "create striped dir under striped dir fails"
19308
19309         touch $DIR/$tdir/striped_dir1/b
19310         mkdir $DIR/$tdir/striped_dir1/dir_b
19311         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
19312                 error "create striped dir under striped dir fails"
19313
19314         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
19315                 error "rename dir under different striped dir should fail"
19316
19317         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
19318                 error "rename striped dir under diff striped dir should fail"
19319
19320         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
19321                 error "rename file under diff striped dirs fails"
19322
19323         rm -rf $DIR/$tdir
19324 }
19325 run_test 300f "check rename cross striped directory"
19326
19327 test_300_check_default_striped_dir()
19328 {
19329         local dirname=$1
19330         local default_count=$2
19331         local default_index=$3
19332         local stripe_count
19333         local stripe_index
19334         local dir_stripe_index
19335         local dir
19336
19337         echo "checking $dirname $default_count $default_index"
19338         $LFS setdirstripe -D -c $default_count -i $default_index \
19339                                 -t all_char $DIR/$tdir/$dirname ||
19340                 error "set default stripe on striped dir error"
19341         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
19342         [ $stripe_count -eq $default_count ] ||
19343                 error "expect $default_count get $stripe_count for $dirname"
19344
19345         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
19346         [ $stripe_index -eq $default_index ] ||
19347                 error "expect $default_index get $stripe_index for $dirname"
19348
19349         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
19350                                                 error "create dirs failed"
19351
19352         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
19353         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
19354         for dir in $(find $DIR/$tdir/$dirname/*); do
19355                 stripe_count=$($LFS getdirstripe -c $dir)
19356                 [ $stripe_count -eq $default_count ] ||
19357                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
19358                 error "stripe count $default_count != $stripe_count for $dir"
19359
19360                 stripe_index=$($LFS getdirstripe -i $dir)
19361                 [ $default_index -eq -1 ] ||
19362                         [ $stripe_index -eq $default_index ] ||
19363                         error "$stripe_index != $default_index for $dir"
19364
19365                 #check default stripe
19366                 stripe_count=$($LFS getdirstripe -D -c $dir)
19367                 [ $stripe_count -eq $default_count ] ||
19368                 error "default count $default_count != $stripe_count for $dir"
19369
19370                 stripe_index=$($LFS getdirstripe -D -i $dir)
19371                 [ $stripe_index -eq $default_index ] ||
19372                 error "default index $default_index != $stripe_index for $dir"
19373         done
19374         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
19375 }
19376
19377 test_300g() {
19378         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19379         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19380                 skip "Need MDS version at least 2.7.55"
19381
19382         local dir
19383         local stripe_count
19384         local stripe_index
19385
19386         mkdir $DIR/$tdir
19387         mkdir $DIR/$tdir/normal_dir
19388
19389         #Checking when client cache stripe index
19390         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
19391         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
19392                 error "create striped_dir failed"
19393
19394         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
19395                 error "create dir0 fails"
19396         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
19397         [ $stripe_index -eq 0 ] ||
19398                 error "dir0 expect index 0 got $stripe_index"
19399
19400         mkdir $DIR/$tdir/striped_dir/dir1 ||
19401                 error "create dir1 fails"
19402         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
19403         [ $stripe_index -eq 1 ] ||
19404                 error "dir1 expect index 1 got $stripe_index"
19405
19406         #check default stripe count/stripe index
19407         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
19408         test_300_check_default_striped_dir normal_dir 1 0
19409         test_300_check_default_striped_dir normal_dir 2 1
19410         test_300_check_default_striped_dir normal_dir 2 -1
19411
19412         #delete default stripe information
19413         echo "delete default stripeEA"
19414         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
19415                 error "set default stripe on striped dir error"
19416
19417         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
19418         for dir in $(find $DIR/$tdir/normal_dir/*); do
19419                 stripe_count=$($LFS getdirstripe -c $dir)
19420                 [ $stripe_count -eq 0 ] ||
19421                         error "expect 1 get $stripe_count for $dir"
19422                 stripe_index=$($LFS getdirstripe -i $dir)
19423                 [ $stripe_index -eq 0 ] ||
19424                         error "expect 0 get $stripe_index for $dir"
19425         done
19426 }
19427 run_test 300g "check default striped directory for normal directory"
19428
19429 test_300h() {
19430         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19431         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19432                 skip "Need MDS version at least 2.7.55"
19433
19434         local dir
19435         local stripe_count
19436
19437         mkdir $DIR/$tdir
19438         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19439                 error "set striped dir error"
19440
19441         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
19442         test_300_check_default_striped_dir striped_dir 1 0
19443         test_300_check_default_striped_dir striped_dir 2 1
19444         test_300_check_default_striped_dir striped_dir 2 -1
19445
19446         #delete default stripe information
19447         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
19448                 error "set default stripe on striped dir error"
19449
19450         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
19451         for dir in $(find $DIR/$tdir/striped_dir/*); do
19452                 stripe_count=$($LFS getdirstripe -c $dir)
19453                 [ $stripe_count -eq 0 ] ||
19454                         error "expect 1 get $stripe_count for $dir"
19455         done
19456 }
19457 run_test 300h "check default striped directory for striped directory"
19458
19459 test_300i() {
19460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19461         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19462         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19463                 skip "Need MDS version at least 2.7.55"
19464
19465         local stripe_count
19466         local file
19467
19468         mkdir $DIR/$tdir
19469
19470         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19471                 error "set striped dir error"
19472
19473         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19474                 error "create files under striped dir failed"
19475
19476         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
19477                 error "set striped hashdir error"
19478
19479         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
19480                 error "create dir0 under hash dir failed"
19481         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
19482                 error "create dir1 under hash dir failed"
19483
19484         # unfortunately, we need to umount to clear dir layout cache for now
19485         # once we fully implement dir layout, we can drop this
19486         umount_client $MOUNT || error "umount failed"
19487         mount_client $MOUNT || error "mount failed"
19488
19489         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
19490         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
19491         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
19492
19493         #set the stripe to be unknown hash type
19494         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
19495         $LCTL set_param fail_loc=0x1901
19496         for ((i = 0; i < 10; i++)); do
19497                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
19498                         error "stat f-$i failed"
19499                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
19500         done
19501
19502         touch $DIR/$tdir/striped_dir/f0 &&
19503                 error "create under striped dir with unknown hash should fail"
19504
19505         $LCTL set_param fail_loc=0
19506
19507         umount_client $MOUNT || error "umount failed"
19508         mount_client $MOUNT || error "mount failed"
19509
19510         return 0
19511 }
19512 run_test 300i "client handle unknown hash type striped directory"
19513
19514 test_300j() {
19515         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19517         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19518                 skip "Need MDS version at least 2.7.55"
19519
19520         local stripe_count
19521         local file
19522
19523         mkdir $DIR/$tdir
19524
19525         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
19526         $LCTL set_param fail_loc=0x1702
19527         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19528                 error "set striped dir error"
19529
19530         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19531                 error "create files under striped dir failed"
19532
19533         $LCTL set_param fail_loc=0
19534
19535         rm -rf $DIR/$tdir || error "unlink striped dir fails"
19536
19537         return 0
19538 }
19539 run_test 300j "test large update record"
19540
19541 test_300k() {
19542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19543         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19544         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19545                 skip "Need MDS version at least 2.7.55"
19546
19547         # this test needs a huge transaction
19548         local kb
19549         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
19550         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
19551
19552         local stripe_count
19553         local file
19554
19555         mkdir $DIR/$tdir
19556
19557         #define OBD_FAIL_LARGE_STRIPE   0x1703
19558         $LCTL set_param fail_loc=0x1703
19559         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
19560                 error "set striped dir error"
19561         $LCTL set_param fail_loc=0
19562
19563         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19564                 error "getstripeddir fails"
19565         rm -rf $DIR/$tdir/striped_dir ||
19566                 error "unlink striped dir fails"
19567
19568         return 0
19569 }
19570 run_test 300k "test large striped directory"
19571
19572 test_300l() {
19573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19574         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19575         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19576                 skip "Need MDS version at least 2.7.55"
19577
19578         local stripe_index
19579
19580         test_mkdir -p $DIR/$tdir/striped_dir
19581         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
19582                         error "chown $RUNAS_ID failed"
19583         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
19584                 error "set default striped dir failed"
19585
19586         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
19587         $LCTL set_param fail_loc=0x80000158
19588         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
19589
19590         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
19591         [ $stripe_index -eq 1 ] ||
19592                 error "expect 1 get $stripe_index for $dir"
19593 }
19594 run_test 300l "non-root user to create dir under striped dir with stale layout"
19595
19596 test_300m() {
19597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19598         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
19599         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19600                 skip "Need MDS version at least 2.7.55"
19601
19602         mkdir -p $DIR/$tdir/striped_dir
19603         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
19604                 error "set default stripes dir error"
19605
19606         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
19607
19608         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
19609         [ $stripe_count -eq 0 ] ||
19610                         error "expect 0 get $stripe_count for a"
19611
19612         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
19613                 error "set default stripes dir error"
19614
19615         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
19616
19617         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
19618         [ $stripe_count -eq 0 ] ||
19619                         error "expect 0 get $stripe_count for b"
19620
19621         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
19622                 error "set default stripes dir error"
19623
19624         mkdir $DIR/$tdir/striped_dir/c &&
19625                 error "default stripe_index is invalid, mkdir c should fails"
19626
19627         rm -rf $DIR/$tdir || error "rmdir fails"
19628 }
19629 run_test 300m "setstriped directory on single MDT FS"
19630
19631 cleanup_300n() {
19632         local list=$(comma_list $(mdts_nodes))
19633
19634         trap 0
19635         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19636 }
19637
19638 test_300n() {
19639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19640         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19641         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19642                 skip "Need MDS version at least 2.7.55"
19643         remote_mds_nodsh && skip "remote MDS with nodsh"
19644
19645         local stripe_index
19646         local list=$(comma_list $(mdts_nodes))
19647
19648         trap cleanup_300n RETURN EXIT
19649         mkdir -p $DIR/$tdir
19650         chmod 777 $DIR/$tdir
19651         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
19652                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19653                 error "create striped dir succeeds with gid=0"
19654
19655         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19656         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
19657                 error "create striped dir fails with gid=-1"
19658
19659         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19660         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
19661                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19662                 error "set default striped dir succeeds with gid=0"
19663
19664
19665         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19666         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
19667                 error "set default striped dir fails with gid=-1"
19668
19669
19670         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19671         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
19672                                         error "create test_dir fails"
19673         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
19674                                         error "create test_dir1 fails"
19675         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
19676                                         error "create test_dir2 fails"
19677         cleanup_300n
19678 }
19679 run_test 300n "non-root user to create dir under striped dir with default EA"
19680
19681 test_300o() {
19682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19683         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19684         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19685                 skip "Need MDS version at least 2.7.55"
19686
19687         local numfree1
19688         local numfree2
19689
19690         mkdir -p $DIR/$tdir
19691
19692         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
19693         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
19694         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
19695                 skip "not enough free inodes $numfree1 $numfree2"
19696         fi
19697
19698         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
19699         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
19700         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
19701                 skip "not enough free space $numfree1 $numfree2"
19702         fi
19703
19704         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
19705                 error "setdirstripe fails"
19706
19707         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
19708                 error "create dirs fails"
19709
19710         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
19711         ls $DIR/$tdir/striped_dir > /dev/null ||
19712                 error "ls striped dir fails"
19713         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
19714                 error "unlink big striped dir fails"
19715 }
19716 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
19717
19718 test_300p() {
19719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19720         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19721         remote_mds_nodsh && skip "remote MDS with nodsh"
19722
19723         mkdir -p $DIR/$tdir
19724
19725         #define OBD_FAIL_OUT_ENOSPC     0x1704
19726         do_facet mds2 lctl set_param fail_loc=0x80001704
19727         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
19728                  && error "create striped directory should fail"
19729
19730         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
19731
19732         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
19733         true
19734 }
19735 run_test 300p "create striped directory without space"
19736
19737 test_300q() {
19738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19739         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19740
19741         local fd=$(free_fd)
19742         local cmd="exec $fd<$tdir"
19743         cd $DIR
19744         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
19745         eval $cmd
19746         cmd="exec $fd<&-"
19747         trap "eval $cmd" EXIT
19748         cd $tdir || error "cd $tdir fails"
19749         rmdir  ../$tdir || error "rmdir $tdir fails"
19750         mkdir local_dir && error "create dir succeeds"
19751         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
19752         eval $cmd
19753         return 0
19754 }
19755 run_test 300q "create remote directory under orphan directory"
19756
19757 test_300r() {
19758         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
19759                 skip "Need MDS version at least 2.7.55" && return
19760         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19761
19762         mkdir $DIR/$tdir
19763
19764         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19765                 error "set striped dir error"
19766
19767         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19768                 error "getstripeddir fails"
19769
19770         local stripe_count
19771         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19772                       awk '/lmv_stripe_count:/ { print $2 }')
19773
19774         [ $MDSCOUNT -ne $stripe_count ] &&
19775                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19776
19777         rm -rf $DIR/$tdir/striped_dir ||
19778                 error "unlink striped dir fails"
19779 }
19780 run_test 300r "test -1 striped directory"
19781
19782 prepare_remote_file() {
19783         mkdir $DIR/$tdir/src_dir ||
19784                 error "create remote source failed"
19785
19786         cp /etc/hosts $DIR/$tdir/src_dir/a ||
19787                  error "cp to remote source failed"
19788         touch $DIR/$tdir/src_dir/a
19789
19790         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
19791                 error "create remote target dir failed"
19792
19793         touch $DIR/$tdir/tgt_dir/b
19794
19795         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
19796                 error "rename dir cross MDT failed!"
19797
19798         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
19799                 error "src_child still exists after rename"
19800
19801         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
19802                 error "missing file(a) after rename"
19803
19804         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
19805                 error "diff after rename"
19806 }
19807
19808 test_310a() {
19809         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19811
19812         local remote_file=$DIR/$tdir/tgt_dir/b
19813
19814         mkdir -p $DIR/$tdir
19815
19816         prepare_remote_file || error "prepare remote file failed"
19817
19818         #open-unlink file
19819         $OPENUNLINK $remote_file $remote_file ||
19820                 error "openunlink $remote_file failed"
19821         $CHECKSTAT -a $remote_file || error "$remote_file exists"
19822 }
19823 run_test 310a "open unlink remote file"
19824
19825 test_310b() {
19826         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19828
19829         local remote_file=$DIR/$tdir/tgt_dir/b
19830
19831         mkdir -p $DIR/$tdir
19832
19833         prepare_remote_file || error "prepare remote file failed"
19834
19835         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19836         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19837         $CHECKSTAT -t file $remote_file || error "check file failed"
19838 }
19839 run_test 310b "unlink remote file with multiple links while open"
19840
19841 test_310c() {
19842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19843         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19844
19845         local remote_file=$DIR/$tdir/tgt_dir/b
19846
19847         mkdir -p $DIR/$tdir
19848
19849         prepare_remote_file || error "prepare remote file failed"
19850
19851         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19852         multiop_bg_pause $remote_file O_uc ||
19853                         error "mulitop failed for remote file"
19854         MULTIPID=$!
19855         $MULTIOP $DIR/$tfile Ouc
19856         kill -USR1 $MULTIPID
19857         wait $MULTIPID
19858 }
19859 run_test 310c "open-unlink remote file with multiple links"
19860
19861 #LU-4825
19862 test_311() {
19863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19864         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19865         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
19866                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
19867         remote_mds_nodsh && skip "remote MDS with nodsh"
19868
19869         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19870         local mdts=$(comma_list $(mdts_nodes))
19871
19872         mkdir -p $DIR/$tdir
19873         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19874         createmany -o $DIR/$tdir/$tfile. 1000
19875
19876         # statfs data is not real time, let's just calculate it
19877         old_iused=$((old_iused + 1000))
19878
19879         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19880                         osp.*OST0000*MDT0000.create_count")
19881         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19882                                 osp.*OST0000*MDT0000.max_create_count")
19883         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
19884
19885         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
19886         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
19887         [ $index -ne 0 ] || error "$tfile stripe index is 0"
19888
19889         unlinkmany $DIR/$tdir/$tfile. 1000
19890
19891         do_nodes $mdts "$LCTL set_param -n \
19892                         osp.*OST0000*.max_create_count=$max_count"
19893         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
19894                 do_nodes $mdts "$LCTL set_param -n \
19895                                 osp.*OST0000*.create_count=$count"
19896         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
19897                         grep "=0" && error "create_count is zero"
19898
19899         local new_iused
19900         for i in $(seq 120); do
19901                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19902                 # system may be too busy to destroy all objs in time, use
19903                 # a somewhat small value to not fail autotest
19904                 [ $((old_iused - new_iused)) -gt 400 ] && break
19905                 sleep 1
19906         done
19907
19908         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
19909         [ $((old_iused - new_iused)) -gt 400 ] ||
19910                 error "objs not destroyed after unlink"
19911 }
19912 run_test 311 "disable OSP precreate, and unlink should destroy objs"
19913
19914 zfs_oid_to_objid()
19915 {
19916         local ost=$1
19917         local objid=$2
19918
19919         local vdevdir=$(dirname $(facet_vdevice $ost))
19920         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
19921         local zfs_zapid=$(do_facet $ost $cmd |
19922                           grep -w "/O/0/d$((objid%32))" -C 5 |
19923                           awk '/Object/{getline; print $1}')
19924         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
19925                           awk "/$objid = /"'{printf $3}')
19926
19927         echo $zfs_objid
19928 }
19929
19930 zfs_object_blksz() {
19931         local ost=$1
19932         local objid=$2
19933
19934         local vdevdir=$(dirname $(facet_vdevice $ost))
19935         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
19936         local blksz=$(do_facet $ost $cmd $objid |
19937                       awk '/dblk/{getline; printf $4}')
19938
19939         case "${blksz: -1}" in
19940                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
19941                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
19942                 *) ;;
19943         esac
19944
19945         echo $blksz
19946 }
19947
19948 test_312() { # LU-4856
19949         remote_ost_nodsh && skip "remote OST with nodsh"
19950         [ "$ost1_FSTYPE" = "zfs" ] ||
19951                 skip_env "the test only applies to zfs"
19952
19953         local max_blksz=$(do_facet ost1 \
19954                           $ZFS get -p recordsize $(facet_device ost1) |
19955                           awk '!/VALUE/{print $3}')
19956
19957         # to make life a little bit easier
19958         $LFS mkdir -c 1 -i 0 $DIR/$tdir
19959         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19960
19961         local tf=$DIR/$tdir/$tfile
19962         touch $tf
19963         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19964
19965         # Get ZFS object id
19966         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19967         # block size change by sequential overwrite
19968         local bs
19969
19970         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
19971                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
19972
19973                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
19974                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
19975         done
19976         rm -f $tf
19977
19978         # block size change by sequential append write
19979         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
19980         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19981         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19982         local count
19983
19984         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
19985                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
19986                         oflag=sync conv=notrunc
19987
19988                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
19989                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
19990                         error "blksz error, actual $blksz, " \
19991                                 "expected: 2 * $count * $PAGE_SIZE"
19992         done
19993         rm -f $tf
19994
19995         # random write
19996         touch $tf
19997         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19998         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19999
20000         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
20001         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20002         [ $blksz -eq $PAGE_SIZE ] ||
20003                 error "blksz error: $blksz, expected: $PAGE_SIZE"
20004
20005         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
20006         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20007         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
20008
20009         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
20010         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20011         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
20012 }
20013 run_test 312 "make sure ZFS adjusts its block size by write pattern"
20014
20015 test_313() {
20016         remote_ost_nodsh && skip "remote OST with nodsh"
20017
20018         local file=$DIR/$tfile
20019
20020         rm -f $file
20021         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
20022
20023         # define OBD_FAIL_TGT_RCVD_EIO           0x720
20024         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20025         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
20026                 error "write should failed"
20027         do_facet ost1 "$LCTL set_param fail_loc=0"
20028         rm -f $file
20029 }
20030 run_test 313 "io should fail after last_rcvd update fail"
20031
20032 test_314() {
20033         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20034
20035         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
20036         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20037         rm -f $DIR/$tfile
20038         wait_delete_completed
20039         do_facet ost1 "$LCTL set_param fail_loc=0"
20040 }
20041 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
20042
20043 test_315() { # LU-618
20044         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
20045
20046         local file=$DIR/$tfile
20047         rm -f $file
20048
20049         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
20050                 error "multiop file write failed"
20051         $MULTIOP $file oO_RDONLY:r4063232_c &
20052         PID=$!
20053
20054         sleep 2
20055
20056         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
20057         kill -USR1 $PID
20058
20059         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
20060         rm -f $file
20061 }
20062 run_test 315 "read should be accounted"
20063
20064 test_316() {
20065         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20066         large_xattr_enabled || skip_env "ea_inode feature disabled"
20067
20068         rm -rf $DIR/$tdir/d
20069         mkdir -p $DIR/$tdir/d
20070         chown nobody $DIR/$tdir/d
20071         touch $DIR/$tdir/d/file
20072
20073         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
20074 }
20075 run_test 316 "lfs mv"
20076
20077 test_317() {
20078         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
20079                 skip "Need MDS version at least 2.11.53"
20080         if [ "$ost1_FSTYPE" == "zfs" ]; then
20081                 skip "LU-10370: no implementation for ZFS"
20082         fi
20083
20084         local trunc_sz
20085         local grant_blk_size
20086
20087         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
20088                         awk '/grant_block_size:/ { print $2; exit; }')
20089         #
20090         # Create File of size 5M. Truncate it to below size's and verify
20091         # blocks count.
20092         #
20093         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
20094                 error "Create file $DIR/$tfile failed"
20095         stack_trap "rm -f $DIR/$tfile" EXIT
20096
20097         for trunc_sz in 2097152 4097 4000 509 0; do
20098                 $TRUNCATE $DIR/$tfile $trunc_sz ||
20099                         error "truncate $tfile to $trunc_sz failed"
20100                 local sz=$(stat --format=%s $DIR/$tfile)
20101                 local blk=$(stat --format=%b $DIR/$tfile)
20102                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
20103                                      grant_blk_size) * 8))
20104
20105                 if [[ $blk -ne $trunc_blk ]]; then
20106                         $(which stat) $DIR/$tfile
20107                         error "Expected Block $trunc_blk got $blk for $tfile"
20108                 fi
20109
20110                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20111                         error "Expected Size $trunc_sz got $sz for $tfile"
20112         done
20113
20114         #
20115         # sparse file test
20116         # Create file with a hole and write actual two blocks. Block count
20117         # must be 16.
20118         #
20119         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
20120                 conv=fsync || error "Create file : $DIR/$tfile"
20121
20122         # Calculate the final truncate size.
20123         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
20124
20125         #
20126         # truncate to size $trunc_sz bytes. Strip the last block
20127         # The block count must drop to 8
20128         #
20129         $TRUNCATE $DIR/$tfile $trunc_sz ||
20130                 error "truncate $tfile to $trunc_sz failed"
20131
20132         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
20133         sz=$(stat --format=%s $DIR/$tfile)
20134         blk=$(stat --format=%b $DIR/$tfile)
20135
20136         if [[ $blk -ne $trunc_bsz ]]; then
20137                 $(which stat) $DIR/$tfile
20138                 error "Expected Block $trunc_bsz got $blk for $tfile"
20139         fi
20140
20141         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20142                 error "Expected Size $trunc_sz got $sz for $tfile"
20143 }
20144 run_test 317 "Verify blocks get correctly update after truncate"
20145
20146 test_318() {
20147         local old_max_active=$($LCTL get_param -n \
20148                             llite.*.max_read_ahead_async_active 2>/dev/null)
20149
20150         $LCTL set_param llite.*.max_read_ahead_async_active=256
20151         local max_active=$($LCTL get_param -n \
20152                            llite.*.max_read_ahead_async_active 2>/dev/null)
20153         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
20154
20155         # currently reset to 0 is unsupported, leave it 512 for now.
20156         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
20157                 error "set max_read_ahead_async_active should fail"
20158
20159         $LCTL set_param llite.*.max_read_ahead_async_active=512
20160         max_active=$($LCTL get_param -n \
20161                      llite.*.max_read_ahead_async_active 2>/dev/null)
20162         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
20163
20164         # restore @max_active
20165         [ $old_max_active -ne 0 ] && $LCTL set_param \
20166                 llite.*.max_read_ahead_async_active=$old_max_active
20167
20168         local old_threshold=$($LCTL get_param -n \
20169                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20170         local max_per_file_mb=$($LCTL get_param -n \
20171                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
20172
20173         local invalid=$(($max_per_file_mb + 1))
20174         $LCTL set_param \
20175                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
20176                         && error "set $invalid should fail"
20177
20178         local valid=$(($invalid - 1))
20179         $LCTL set_param \
20180                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
20181                         error "set $valid should succeed"
20182         local threshold=$($LCTL get_param -n \
20183                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20184         [ $threshold -eq $valid ] || error \
20185                 "expect threshold $valid got $threshold"
20186         $LCTL set_param \
20187                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
20188 }
20189 run_test 318 "Verify async readahead tunables"
20190
20191 test_319() {
20192         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
20193
20194         local before=$(date +%s)
20195         local evict
20196         local mdir=$DIR/$tdir
20197         local file=$mdir/xxx
20198
20199         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
20200         touch $file
20201
20202 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
20203         $LCTL set_param fail_val=5 fail_loc=0x8000032c
20204         $LFS mv -m1 $file &
20205
20206         sleep 1
20207         dd if=$file of=/dev/null
20208         wait
20209         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
20210           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
20211
20212         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
20213 }
20214 run_test 319 "lost lease lock on migrate error"
20215
20216 test_fake_rw() {
20217         local read_write=$1
20218         if [ "$read_write" = "write" ]; then
20219                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
20220         elif [ "$read_write" = "read" ]; then
20221                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
20222         else
20223                 error "argument error"
20224         fi
20225
20226         # turn off debug for performance testing
20227         local saved_debug=$($LCTL get_param -n debug)
20228         $LCTL set_param debug=0
20229
20230         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20231
20232         # get ost1 size - lustre-OST0000
20233         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
20234         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
20235         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
20236
20237         if [ "$read_write" = "read" ]; then
20238                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
20239         fi
20240
20241         local start_time=$(date +%s.%N)
20242         $dd_cmd bs=1M count=$blocks oflag=sync ||
20243                 error "real dd $read_write error"
20244         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
20245
20246         if [ "$read_write" = "write" ]; then
20247                 rm -f $DIR/$tfile
20248         fi
20249
20250         # define OBD_FAIL_OST_FAKE_RW           0x238
20251         do_facet ost1 $LCTL set_param fail_loc=0x238
20252
20253         local start_time=$(date +%s.%N)
20254         $dd_cmd bs=1M count=$blocks oflag=sync ||
20255                 error "fake dd $read_write error"
20256         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
20257
20258         if [ "$read_write" = "write" ]; then
20259                 # verify file size
20260                 cancel_lru_locks osc
20261                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
20262                         error "$tfile size not $blocks MB"
20263         fi
20264         do_facet ost1 $LCTL set_param fail_loc=0
20265
20266         echo "fake $read_write $duration_fake vs. normal $read_write" \
20267                 "$duration in seconds"
20268         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
20269                 error_not_in_vm "fake write is slower"
20270
20271         $LCTL set_param -n debug="$saved_debug"
20272         rm -f $DIR/$tfile
20273 }
20274 test_399a() { # LU-7655 for OST fake write
20275         remote_ost_nodsh && skip "remote OST with nodsh"
20276
20277         test_fake_rw write
20278 }
20279 run_test 399a "fake write should not be slower than normal write"
20280
20281 test_399b() { # LU-8726 for OST fake read
20282         remote_ost_nodsh && skip "remote OST with nodsh"
20283         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
20284                 skip_env "ldiskfs only test"
20285         fi
20286
20287         test_fake_rw read
20288 }
20289 run_test 399b "fake read should not be slower than normal read"
20290
20291 test_400a() { # LU-1606, was conf-sanity test_74
20292         if ! which $CC > /dev/null 2>&1; then
20293                 skip_env "$CC is not installed"
20294         fi
20295
20296         local extra_flags=''
20297         local out=$TMP/$tfile
20298         local prefix=/usr/include/lustre
20299         local prog
20300
20301         if ! [[ -d $prefix ]]; then
20302                 # Assume we're running in tree and fixup the include path.
20303                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
20304                 extra_flags+=" -L$LUSTRE/utils/.lib"
20305         fi
20306
20307         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
20308                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
20309                         error "client api broken"
20310         done
20311         rm -f $out
20312 }
20313 run_test 400a "Lustre client api program can compile and link"
20314
20315 test_400b() { # LU-1606, LU-5011
20316         local header
20317         local out=$TMP/$tfile
20318         local prefix=/usr/include/linux/lustre
20319
20320         # We use a hard coded prefix so that this test will not fail
20321         # when run in tree. There are headers in lustre/include/lustre/
20322         # that are not packaged (like lustre_idl.h) and have more
20323         # complicated include dependencies (like config.h and lnet/types.h).
20324         # Since this test about correct packaging we just skip them when
20325         # they don't exist (see below) rather than try to fixup cppflags.
20326
20327         if ! which $CC > /dev/null 2>&1; then
20328                 skip_env "$CC is not installed"
20329         fi
20330
20331         for header in $prefix/*.h; do
20332                 if ! [[ -f "$header" ]]; then
20333                         continue
20334                 fi
20335
20336                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
20337                         continue # lustre_ioctl.h is internal header
20338                 fi
20339
20340                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
20341                         error "cannot compile '$header'"
20342         done
20343         rm -f $out
20344 }
20345 run_test 400b "packaged headers can be compiled"
20346
20347 test_401a() { #LU-7437
20348         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
20349         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
20350
20351         #count the number of parameters by "list_param -R"
20352         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
20353         #count the number of parameters by listing proc files
20354         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
20355         echo "proc_dirs='$proc_dirs'"
20356         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
20357         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
20358                       sort -u | wc -l)
20359
20360         [ $params -eq $procs ] ||
20361                 error "found $params parameters vs. $procs proc files"
20362
20363         # test the list_param -D option only returns directories
20364         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
20365         #count the number of parameters by listing proc directories
20366         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
20367                 sort -u | wc -l)
20368
20369         [ $params -eq $procs ] ||
20370                 error "found $params parameters vs. $procs proc files"
20371 }
20372 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
20373
20374 test_401b() {
20375         local save=$($LCTL get_param -n jobid_var)
20376         local tmp=testing
20377
20378         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
20379                 error "no error returned when setting bad parameters"
20380
20381         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
20382         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
20383
20384         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
20385         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
20386         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
20387 }
20388 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
20389
20390 test_401c() {
20391         local jobid_var_old=$($LCTL get_param -n jobid_var)
20392         local jobid_var_new
20393
20394         $LCTL set_param jobid_var= &&
20395                 error "no error returned for 'set_param a='"
20396
20397         jobid_var_new=$($LCTL get_param -n jobid_var)
20398         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20399                 error "jobid_var was changed by setting without value"
20400
20401         $LCTL set_param jobid_var &&
20402                 error "no error returned for 'set_param a'"
20403
20404         jobid_var_new=$($LCTL get_param -n jobid_var)
20405         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20406                 error "jobid_var was changed by setting without value"
20407 }
20408 run_test 401c "Verify 'lctl set_param' without value fails in either format."
20409
20410 test_401d() {
20411         local jobid_var_old=$($LCTL get_param -n jobid_var)
20412         local jobid_var_new
20413         local new_value="foo=bar"
20414
20415         $LCTL set_param jobid_var=$new_value ||
20416                 error "'set_param a=b' did not accept a value containing '='"
20417
20418         jobid_var_new=$($LCTL get_param -n jobid_var)
20419         [[ "$jobid_var_new" == "$new_value" ]] ||
20420                 error "'set_param a=b' failed on a value containing '='"
20421
20422         # Reset the jobid_var to test the other format
20423         $LCTL set_param jobid_var=$jobid_var_old
20424         jobid_var_new=$($LCTL get_param -n jobid_var)
20425         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20426                 error "failed to reset jobid_var"
20427
20428         $LCTL set_param jobid_var $new_value ||
20429                 error "'set_param a b' did not accept a value containing '='"
20430
20431         jobid_var_new=$($LCTL get_param -n jobid_var)
20432         [[ "$jobid_var_new" == "$new_value" ]] ||
20433                 error "'set_param a b' failed on a value containing '='"
20434
20435         $LCTL set_param jobid_var $jobid_var_old
20436         jobid_var_new=$($LCTL get_param -n jobid_var)
20437         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20438                 error "failed to reset jobid_var"
20439 }
20440 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
20441
20442 test_402() {
20443         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
20444         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
20445                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
20446         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
20447                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
20448                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
20449         remote_mds_nodsh && skip "remote MDS with nodsh"
20450
20451         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
20452 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
20453         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
20454         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
20455                 echo "Touch failed - OK"
20456 }
20457 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
20458
20459 test_403() {
20460         local file1=$DIR/$tfile.1
20461         local file2=$DIR/$tfile.2
20462         local tfile=$TMP/$tfile
20463
20464         rm -f $file1 $file2 $tfile
20465
20466         touch $file1
20467         ln $file1 $file2
20468
20469         # 30 sec OBD_TIMEOUT in ll_getattr()
20470         # right before populating st_nlink
20471         $LCTL set_param fail_loc=0x80001409
20472         stat -c %h $file1 > $tfile &
20473
20474         # create an alias, drop all locks and reclaim the dentry
20475         < $file2
20476         cancel_lru_locks mdc
20477         cancel_lru_locks osc
20478         sysctl -w vm.drop_caches=2
20479
20480         wait
20481
20482         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
20483
20484         rm -f $tfile $file1 $file2
20485 }
20486 run_test 403 "i_nlink should not drop to zero due to aliasing"
20487
20488 test_404() { # LU-6601
20489         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
20490                 skip "Need server version newer than 2.8.52"
20491         remote_mds_nodsh && skip "remote MDS with nodsh"
20492
20493         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
20494                 awk '/osp .*-osc-MDT/ { print $4}')
20495
20496         local osp
20497         for osp in $mosps; do
20498                 echo "Deactivate: " $osp
20499                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
20500                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20501                         awk -vp=$osp '$4 == p { print $2 }')
20502                 [ $stat = IN ] || {
20503                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20504                         error "deactivate error"
20505                 }
20506                 echo "Activate: " $osp
20507                 do_facet $SINGLEMDS $LCTL --device %$osp activate
20508                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20509                         awk -vp=$osp '$4 == p { print $2 }')
20510                 [ $stat = UP ] || {
20511                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20512                         error "activate error"
20513                 }
20514         done
20515 }
20516 run_test 404 "validate manual {de}activated works properly for OSPs"
20517
20518 test_405() {
20519         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20520         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
20521                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
20522                         skip "Layout swap lock is not supported"
20523
20524         check_swap_layouts_support
20525
20526         test_mkdir $DIR/$tdir
20527         swap_lock_test -d $DIR/$tdir ||
20528                 error "One layout swap locked test failed"
20529 }
20530 run_test 405 "Various layout swap lock tests"
20531
20532 test_406() {
20533         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20534         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20535         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20537         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
20538                 skip "Need MDS version at least 2.8.50"
20539
20540         local def_stripe_size=$($LFS getstripe -S $MOUNT)
20541         local test_pool=$TESTNAME
20542
20543         pool_add $test_pool || error "pool_add failed"
20544         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
20545                 error "pool_add_targets failed"
20546
20547         save_layout_restore_at_exit $MOUNT
20548
20549         # parent set default stripe count only, child will stripe from both
20550         # parent and fs default
20551         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
20552                 error "setstripe $MOUNT failed"
20553         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
20554         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
20555         for i in $(seq 10); do
20556                 local f=$DIR/$tdir/$tfile.$i
20557                 touch $f || error "touch failed"
20558                 local count=$($LFS getstripe -c $f)
20559                 [ $count -eq $OSTCOUNT ] ||
20560                         error "$f stripe count $count != $OSTCOUNT"
20561                 local offset=$($LFS getstripe -i $f)
20562                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
20563                 local size=$($LFS getstripe -S $f)
20564                 [ $size -eq $((def_stripe_size * 2)) ] ||
20565                         error "$f stripe size $size != $((def_stripe_size * 2))"
20566                 local pool=$($LFS getstripe -p $f)
20567                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
20568         done
20569
20570         # change fs default striping, delete parent default striping, now child
20571         # will stripe from new fs default striping only
20572         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
20573                 error "change $MOUNT default stripe failed"
20574         $LFS setstripe -c 0 $DIR/$tdir ||
20575                 error "delete $tdir default stripe failed"
20576         for i in $(seq 11 20); do
20577                 local f=$DIR/$tdir/$tfile.$i
20578                 touch $f || error "touch $f failed"
20579                 local count=$($LFS getstripe -c $f)
20580                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
20581                 local offset=$($LFS getstripe -i $f)
20582                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
20583                 local size=$($LFS getstripe -S $f)
20584                 [ $size -eq $def_stripe_size ] ||
20585                         error "$f stripe size $size != $def_stripe_size"
20586                 local pool=$($LFS getstripe -p $f)
20587                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
20588         done
20589
20590         unlinkmany $DIR/$tdir/$tfile. 1 20
20591
20592         local f=$DIR/$tdir/$tfile
20593         pool_remove_all_targets $test_pool $f
20594         pool_remove $test_pool $f
20595 }
20596 run_test 406 "DNE support fs default striping"
20597
20598 test_407() {
20599         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20600         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20601                 skip "Need MDS version at least 2.8.55"
20602         remote_mds_nodsh && skip "remote MDS with nodsh"
20603
20604         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
20605                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
20606         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
20607                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
20608         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
20609
20610         #define OBD_FAIL_DT_TXN_STOP    0x2019
20611         for idx in $(seq $MDSCOUNT); do
20612                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
20613         done
20614         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
20615         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
20616                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
20617         true
20618 }
20619 run_test 407 "transaction fail should cause operation fail"
20620
20621 test_408() {
20622         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20623
20624         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
20625         lctl set_param fail_loc=0x8000040a
20626         # let ll_prepare_partial_page() fail
20627         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
20628
20629         rm -f $DIR/$tfile
20630
20631         # create at least 100 unused inodes so that
20632         # shrink_icache_memory(0) should not return 0
20633         touch $DIR/$tfile-{0..100}
20634         rm -f $DIR/$tfile-{0..100}
20635         sync
20636
20637         echo 2 > /proc/sys/vm/drop_caches
20638 }
20639 run_test 408 "drop_caches should not hang due to page leaks"
20640
20641 test_409()
20642 {
20643         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20644
20645         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
20646         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
20647         touch $DIR/$tdir/guard || error "(2) Fail to create"
20648
20649         local PREFIX=$(str_repeat 'A' 128)
20650         echo "Create 1K hard links start at $(date)"
20651         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20652                 error "(3) Fail to hard link"
20653
20654         echo "Links count should be right although linkEA overflow"
20655         stat $DIR/$tdir/guard || error "(4) Fail to stat"
20656         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
20657         [ $linkcount -eq 1001 ] ||
20658                 error "(5) Unexpected hard links count: $linkcount"
20659
20660         echo "List all links start at $(date)"
20661         ls -l $DIR/$tdir/foo > /dev/null ||
20662                 error "(6) Fail to list $DIR/$tdir/foo"
20663
20664         echo "Unlink hard links start at $(date)"
20665         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20666                 error "(7) Fail to unlink"
20667         echo "Unlink hard links finished at $(date)"
20668 }
20669 run_test 409 "Large amount of cross-MDTs hard links on the same file"
20670
20671 test_410()
20672 {
20673         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
20674                 skip "Need client version at least 2.9.59"
20675
20676         # Create a file, and stat it from the kernel
20677         local testfile=$DIR/$tfile
20678         touch $testfile
20679
20680         local run_id=$RANDOM
20681         local my_ino=$(stat --format "%i" $testfile)
20682
20683         # Try to insert the module. This will always fail as the
20684         # module is designed to not be inserted.
20685         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
20686             &> /dev/null
20687
20688         # Anything but success is a test failure
20689         dmesg | grep -q \
20690             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
20691             error "no inode match"
20692 }
20693 run_test 410 "Test inode number returned from kernel thread"
20694
20695 cleanup_test411_cgroup() {
20696         trap 0
20697         rmdir "$1"
20698 }
20699
20700 test_411() {
20701         local cg_basedir=/sys/fs/cgroup/memory
20702         # LU-9966
20703         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
20704                 skip "no setup for cgroup"
20705
20706         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
20707                 error "test file creation failed"
20708         cancel_lru_locks osc
20709
20710         # Create a very small memory cgroup to force a slab allocation error
20711         local cgdir=$cg_basedir/osc_slab_alloc
20712         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
20713         trap "cleanup_test411_cgroup $cgdir" EXIT
20714         echo 2M > $cgdir/memory.kmem.limit_in_bytes
20715         echo 1M > $cgdir/memory.limit_in_bytes
20716
20717         # Should not LBUG, just be killed by oom-killer
20718         # dd will return 0 even allocation failure in some environment.
20719         # So don't check return value
20720         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
20721         cleanup_test411_cgroup $cgdir
20722
20723         return 0
20724 }
20725 run_test 411 "Slab allocation error with cgroup does not LBUG"
20726
20727 test_412() {
20728         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20729         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20730                 skip "Need server version at least 2.10.55"
20731         fi
20732
20733         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
20734                 error "mkdir failed"
20735         $LFS getdirstripe $DIR/$tdir
20736         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20737         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
20738                 error "expect $((MDSCOUT - 1)) get $stripe_index"
20739         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
20740         [ $stripe_count -eq 2 ] ||
20741                 error "expect 2 get $stripe_count"
20742 }
20743 run_test 412 "mkdir on specific MDTs"
20744
20745 test_413a() {
20746         [ $MDSCOUNT -lt 2 ] &&
20747                 skip "We need at least 2 MDTs for this test"
20748
20749         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20750                 skip "Need server version at least 2.10.55"
20751         fi
20752
20753         mkdir $DIR/$tdir || error "mkdir failed"
20754
20755         # find MDT that is the most full
20756         local max=$($LFS df | grep MDT |
20757                 awk 'BEGIN { a=0 }
20758                         { sub("%", "", $5)
20759                           if (0+$5 >= a)
20760                           {
20761                                 a = $5
20762                                 b = $6
20763                           }
20764                         }
20765                      END { split(b, c, ":")
20766                            sub("]", "", c[2])
20767                            print c[2]
20768                          }')
20769
20770         for i in $(seq $((MDSCOUNT - 1))); do
20771                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
20772                         error "mkdir d$i failed"
20773                 $LFS getdirstripe $DIR/$tdir/d$i
20774                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
20775                 [ $stripe_index -ne $max ] ||
20776                         error "don't expect $max"
20777         done
20778 }
20779 run_test 413a "mkdir on less full MDTs"
20780
20781 test_413b() {
20782         [ $MDSCOUNT -lt 2 ] &&
20783                 skip "We need at least 2 MDTs for this test"
20784
20785         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
20786                 skip "Need server version at least 2.12.52"
20787
20788         mkdir $DIR/$tdir || error "mkdir failed"
20789         $LFS setdirstripe -D -i -1 -H space $DIR/$tdir ||
20790                 error "setdirstripe failed"
20791
20792         local qos_prio_free
20793         local qos_threshold_rr
20794         local count
20795
20796         qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
20797         qos_prio_free=${qos_prio_free%%%}
20798         qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr | head -n1)
20799         qos_threshold_rr=${qos_threshold_rr%%%}
20800         qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
20801
20802         stack_trap "$LCTL set_param lmv.*.qos_prio_free=$qos_prio_free" EXIT
20803         stack_trap "$LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr" \
20804                 EXIT
20805         stack_trap "$LCTL set_param lmv.*.qos_maxage=$qos_maxage" EXIT
20806
20807         echo "mkdir with roundrobin"
20808
20809         $LCTL set_param lmv.*.qos_threshold_rr=100
20810         for i in $(seq $((100 * MDSCOUNT))); do
20811                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20812         done
20813         for i in $(seq $MDSCOUNT); do
20814                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20815                         wc -w)
20816                 echo "$count directories created on MDT$((i - 1))"
20817                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
20818         done
20819
20820         rm -rf $DIR/$tdir/*
20821
20822         $LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr
20823         # Shorten statfs result age, so that it can be updated in time
20824         $LCTL set_param lmv.*.qos_maxage=1
20825         sleep_maxage
20826
20827         local ffree
20828         local bavail
20829         local max
20830         local min
20831         local max_index
20832         local min_index
20833         local tmp
20834
20835         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
20836         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
20837         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
20838
20839         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
20840         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
20841         max_index=0
20842         min_index=0
20843         for ((i = 1; i < ${#ffree[@]}; i++)); do
20844                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
20845                 if [ $tmp -gt $max ]; then
20846                         max=$tmp
20847                         max_index=$i
20848                 fi
20849                 if [ $tmp -lt $min ]; then
20850                         min=$tmp
20851                         min_index=$i
20852                 fi
20853         done
20854
20855         [ ${ffree[min_index]} -eq 0 ] &&
20856                 skip "no free files in MDT$min_index"
20857         [ ${ffree[min_index]} -gt 100000000 ] &&
20858                 skip "too much free files in MDT$min_index"
20859
20860         # Check if we need to generate uneven MDTs
20861         local threshold=50
20862         local diff=$(((max - min ) * 100 / min))
20863         local value="$(generate_string 1024)"
20864         local i
20865
20866         while [ $diff -lt $threshold ]; do
20867                 # generate uneven MDTs, create till $threshold% diff
20868                 echo -n "weight diff=$diff% must be > $threshold% ..."
20869                 count=$((${ffree[min_index]} / 10))
20870                 # 50 sec per 10000 files in vm
20871                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
20872                         skip "$count files to create"
20873                 echo "Fill MDT$min_index with $count files"
20874                 [ -d $DIR/$tdir-MDT$min_index ] ||
20875                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
20876                         error "mkdir $tdir-MDT$min_index failed"
20877                 for i in $(seq $count); do
20878                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
20879                                 $DIR/$tdir-MDT$min_index/f$i > /dev/null ||
20880                                 error "create f$i failed"
20881                         setfattr -n user.413b -v $value \
20882                                 $DIR/$tdir-MDT$min_index/f$i ||
20883                                 error "setfattr f$i failed"
20884                 done
20885
20886                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
20887                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
20888                 max=$(((${ffree[max_index]} >> 8) * \
20889                         (${bavail[max_index]} * bsize >> 16)))
20890                 min=$(((${ffree[min_index]} >> 8) * \
20891                         (${bavail[min_index]} * bsize >> 16)))
20892                 diff=$(((max - min) * 100 / min))
20893         done
20894
20895         echo "MDT filesfree available: ${ffree[@]}"
20896         echo "MDT blocks available: ${bavail[@]}"
20897         echo "weight diff=$diff%"
20898
20899         echo "mkdir with balanced space usage"
20900         $LCTL set_param lmv.*.qos_prio_free=100
20901         for i in $(seq $((100 * MDSCOUNT))); do
20902                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20903         done
20904
20905         for i in $(seq $MDSCOUNT); do
20906                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20907                         wc -w)
20908                 echo "$count directories created on MDT$((i - 1))"
20909         done
20910
20911         max=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$max_index$ | wc -l)
20912         min=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$min_index$ | wc -l)
20913
20914         [ $((max - min)) -lt 10 ] &&
20915                 error "subdirs shouldn't be evenly distributed"
20916
20917         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20918
20919         $LFS setdirstripe -D -d $DIR/$tdir || error "setdirstripe -d failed"
20920         getfattr -n trusted.dmv $DIR/$tdir &&
20921                 error "default dir layout exists" || true
20922 }
20923 run_test 413b "mkdir with balanced space usage"
20924
20925 test_414() {
20926 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
20927         $LCTL set_param fail_loc=0x80000521
20928         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
20929         rm -f $DIR/$tfile
20930 }
20931 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
20932
20933 test_415() {
20934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20935         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
20936                 skip "Need server version at least 2.11.52"
20937
20938         # LU-11102
20939         local total
20940         local setattr_pid
20941         local start_time
20942         local end_time
20943         local duration
20944
20945         total=500
20946         # this test may be slow on ZFS
20947         [ "$mds1_FSTYPE" == "zfs" ] && total=100
20948
20949         # though this test is designed for striped directory, let's test normal
20950         # directory too since lock is always saved as CoS lock.
20951         test_mkdir $DIR/$tdir || error "mkdir $tdir"
20952         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
20953
20954         (
20955                 while true; do
20956                         touch $DIR/$tdir
20957                 done
20958         ) &
20959         setattr_pid=$!
20960
20961         start_time=$(date +%s)
20962         for i in $(seq $total); do
20963                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
20964                         > /dev/null
20965         done
20966         end_time=$(date +%s)
20967         duration=$((end_time - start_time))
20968
20969         kill -9 $setattr_pid
20970
20971         echo "rename $total files took $duration sec"
20972         [ $duration -lt 100 ] || error "rename took $duration sec"
20973 }
20974 run_test 415 "lock revoke is not missing"
20975
20976 test_416() {
20977         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
20978                 skip "Need server version at least 2.11.55"
20979
20980         # define OBD_FAIL_OSD_TXN_START    0x19a
20981         do_facet mds1 lctl set_param fail_loc=0x19a
20982
20983         lfs mkdir -c $MDSCOUNT $DIR/$tdir
20984
20985         true
20986 }
20987 run_test 416 "transaction start failure won't cause system hung"
20988
20989 cleanup_417() {
20990         trap 0
20991         do_nodes $(comma_list $(mdts_nodes)) \
20992                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
20993         do_nodes $(comma_list $(mdts_nodes)) \
20994                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
20995         do_nodes $(comma_list $(mdts_nodes)) \
20996                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
20997 }
20998
20999 test_417() {
21000         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21001         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
21002                 skip "Need MDS version at least 2.11.56"
21003
21004         trap cleanup_417 RETURN EXIT
21005
21006         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
21007         do_nodes $(comma_list $(mdts_nodes)) \
21008                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
21009         $LFS migrate -m 0 $DIR/$tdir.1 &&
21010                 error "migrate dir $tdir.1 should fail"
21011
21012         do_nodes $(comma_list $(mdts_nodes)) \
21013                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
21014         $LFS mkdir -i 1 $DIR/$tdir.2 &&
21015                 error "create remote dir $tdir.2 should fail"
21016
21017         do_nodes $(comma_list $(mdts_nodes)) \
21018                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
21019         $LFS mkdir -c 2 $DIR/$tdir.3 &&
21020                 error "create striped dir $tdir.3 should fail"
21021         true
21022 }
21023 run_test 417 "disable remote dir, striped dir and dir migration"
21024
21025 # Checks that the outputs of df [-i] and lfs df [-i] match
21026 #
21027 # usage: check_lfs_df <blocks | inodes> <mountpoint>
21028 check_lfs_df() {
21029         local dir=$2
21030         local inodes
21031         local df_out
21032         local lfs_df_out
21033         local count
21034         local passed=false
21035
21036         # blocks or inodes
21037         [ "$1" == "blocks" ] && inodes= || inodes="-i"
21038
21039         for count in {1..100}; do
21040                 cancel_lru_locks
21041                 sync; sleep 0.2
21042
21043                 # read the lines of interest
21044                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
21045                         error "df $inodes $dir | tail -n +2 failed"
21046                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
21047                         error "lfs df $inodes $dir | grep summary: failed"
21048
21049                 # skip first substrings of each output as they are different
21050                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
21051                 # compare the two outputs
21052                 passed=true
21053                 for i in {1..5}; do
21054                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
21055                 done
21056                 $passed && break
21057         done
21058
21059         if ! $passed; then
21060                 df -P $inodes $dir
21061                 echo
21062                 lfs df $inodes $dir
21063                 error "df and lfs df $1 output mismatch: "      \
21064                       "df ${inodes}: ${df_out[*]}, "            \
21065                       "lfs df ${inodes}: ${lfs_df_out[*]}"
21066         fi
21067 }
21068
21069 test_418() {
21070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21071
21072         local dir=$DIR/$tdir
21073         local numfiles=$((RANDOM % 4096 + 2))
21074         local numblocks=$((RANDOM % 256 + 1))
21075
21076         wait_delete_completed
21077         test_mkdir $dir
21078
21079         # check block output
21080         check_lfs_df blocks $dir
21081         # check inode output
21082         check_lfs_df inodes $dir
21083
21084         # create a single file and retest
21085         echo "Creating a single file and testing"
21086         createmany -o $dir/$tfile- 1 &>/dev/null ||
21087                 error "creating 1 file in $dir failed"
21088         check_lfs_df blocks $dir
21089         check_lfs_df inodes $dir
21090
21091         # create a random number of files
21092         echo "Creating $((numfiles - 1)) files and testing"
21093         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
21094                 error "creating $((numfiles - 1)) files in $dir failed"
21095
21096         # write a random number of blocks to the first test file
21097         echo "Writing $numblocks 4K blocks and testing"
21098         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
21099                 count=$numblocks &>/dev/null ||
21100                 error "dd to $dir/${tfile}-0 failed"
21101
21102         # retest
21103         check_lfs_df blocks $dir
21104         check_lfs_df inodes $dir
21105
21106         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
21107                 error "unlinking $numfiles files in $dir failed"
21108 }
21109 run_test 418 "df and lfs df outputs match"
21110
21111 test_419()
21112 {
21113         local dir=$DIR/$tdir
21114
21115         mkdir -p $dir
21116         touch $dir/file
21117
21118         cancel_lru_locks mdc
21119
21120         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
21121         $LCTL set_param fail_loc=0x1410
21122         cat $dir/file
21123         $LCTL set_param fail_loc=0
21124         rm -rf $dir
21125 }
21126 run_test 419 "Verify open file by name doesn't crash kernel"
21127
21128 test_420()
21129 {
21130         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
21131                 skip "Need MDS version at least 2.12.53"
21132
21133         local SAVE_UMASK=$(umask)
21134         local dir=$DIR/$tdir
21135         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
21136
21137         mkdir -p $dir
21138         umask 0000
21139         mkdir -m03777 $dir/testdir
21140         ls -dn $dir/testdir
21141         # Need to remove trailing '.' when SELinux is enabled
21142         local dirperms=$(ls -dn $dir/testdir |
21143                          awk '{ sub(/\.$/, "", $1); print $1}')
21144         [ $dirperms == "drwxrwsrwt" ] ||
21145                 error "incorrect perms on $dir/testdir"
21146
21147         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
21148                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
21149         ls -n $dir/testdir/testfile
21150         local fileperms=$(ls -n $dir/testdir/testfile |
21151                           awk '{ sub(/\.$/, "", $1); print $1}')
21152         [ $fileperms == "-rwxr-xr-x" ] ||
21153                 error "incorrect perms on $dir/testdir/testfile"
21154
21155         umask $SAVE_UMASK
21156 }
21157 run_test 420 "clear SGID bit on non-directories for non-members"
21158
21159 test_421a() {
21160         local cnt
21161         local fid1
21162         local fid2
21163
21164         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21165                 skip "Need MDS version at least 2.12.54"
21166
21167         test_mkdir $DIR/$tdir
21168         createmany -o $DIR/$tdir/f 3
21169         cnt=$(ls -1 $DIR/$tdir | wc -l)
21170         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21171
21172         fid1=$(lfs path2fid $DIR/$tdir/f1)
21173         fid2=$(lfs path2fid $DIR/$tdir/f2)
21174         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
21175
21176         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
21177         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
21178
21179         cnt=$(ls -1 $DIR/$tdir | wc -l)
21180         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21181
21182         rm -f $DIR/$tdir/f3 || error "can't remove f3"
21183         createmany -o $DIR/$tdir/f 3
21184         cnt=$(ls -1 $DIR/$tdir | wc -l)
21185         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21186
21187         fid1=$(lfs path2fid $DIR/$tdir/f1)
21188         fid2=$(lfs path2fid $DIR/$tdir/f2)
21189         echo "remove using fsname $FSNAME"
21190         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
21191
21192         cnt=$(ls -1 $DIR/$tdir | wc -l)
21193         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21194 }
21195 run_test 421a "simple rm by fid"
21196
21197 test_421b() {
21198         local cnt
21199         local FID1
21200         local FID2
21201
21202         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21203                 skip "Need MDS version at least 2.12.54"
21204
21205         test_mkdir $DIR/$tdir
21206         createmany -o $DIR/$tdir/f 3
21207         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
21208         MULTIPID=$!
21209
21210         FID1=$(lfs path2fid $DIR/$tdir/f1)
21211         FID2=$(lfs path2fid $DIR/$tdir/f2)
21212         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
21213
21214         kill -USR1 $MULTIPID
21215         wait
21216
21217         cnt=$(ls $DIR/$tdir | wc -l)
21218         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
21219 }
21220 run_test 421b "rm by fid on open file"
21221
21222 test_421c() {
21223         local cnt
21224         local FIDS
21225
21226         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21227                 skip "Need MDS version at least 2.12.54"
21228
21229         test_mkdir $DIR/$tdir
21230         createmany -o $DIR/$tdir/f 3
21231         touch $DIR/$tdir/$tfile
21232         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
21233         cnt=$(ls -1 $DIR/$tdir | wc -l)
21234         [ $cnt != 184 ] && error "unexpected #files: $cnt"
21235
21236         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
21237         $LFS rmfid $DIR $FID1 || error "rmfid failed"
21238
21239         cnt=$(ls $DIR/$tdir | wc -l)
21240         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
21241 }
21242 run_test 421c "rm by fid against hardlinked files"
21243
21244 test_421d() {
21245         local cnt
21246         local FIDS
21247
21248         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21249                 skip "Need MDS version at least 2.12.54"
21250
21251         test_mkdir $DIR/$tdir
21252         createmany -o $DIR/$tdir/f 4097
21253         cnt=$(ls -1 $DIR/$tdir | wc -l)
21254         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
21255
21256         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
21257         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21258
21259         cnt=$(ls $DIR/$tdir | wc -l)
21260         rm -rf $DIR/$tdir
21261         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21262 }
21263 run_test 421d "rmfid en masse"
21264
21265 test_421e() {
21266         local cnt
21267         local FID
21268
21269         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21270         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21271                 skip "Need MDS version at least 2.12.54"
21272
21273         mkdir -p $DIR/$tdir
21274         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21275         createmany -o $DIR/$tdir/striped_dir/f 512
21276         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21277         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21278
21279         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21280                 sed "s/[/][^:]*://g")
21281         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21282
21283         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21284         rm -rf $DIR/$tdir
21285         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21286 }
21287 run_test 421e "rmfid in DNE"
21288
21289 test_421f() {
21290         local cnt
21291         local FID
21292
21293         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21294                 skip "Need MDS version at least 2.12.54"
21295
21296         test_mkdir $DIR/$tdir
21297         touch $DIR/$tdir/f
21298         cnt=$(ls -1 $DIR/$tdir | wc -l)
21299         [ $cnt != 1 ] && error "unexpected #files: $cnt"
21300
21301         FID=$(lfs path2fid $DIR/$tdir/f)
21302         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
21303         # rmfid should fail
21304         cnt=$(ls -1 $DIR/$tdir | wc -l)
21305         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
21306
21307         chmod a+rw $DIR/$tdir
21308         ls -la $DIR/$tdir
21309         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
21310         # rmfid should fail
21311         cnt=$(ls -1 $DIR/$tdir | wc -l)
21312         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
21313
21314         rm -f $DIR/$tdir/f
21315         $RUNAS touch $DIR/$tdir/f
21316         FID=$(lfs path2fid $DIR/$tdir/f)
21317         echo "rmfid as root"
21318         $LFS rmfid $DIR $FID || error "rmfid as root failed"
21319         cnt=$(ls -1 $DIR/$tdir | wc -l)
21320         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
21321
21322         rm -f $DIR/$tdir/f
21323         $RUNAS touch $DIR/$tdir/f
21324         cnt=$(ls -1 $DIR/$tdir | wc -l)
21325         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
21326         FID=$(lfs path2fid $DIR/$tdir/f)
21327         # rmfid w/o user_fid2path mount option should fail
21328         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
21329         cnt=$(ls -1 $DIR/$tdir | wc -l)
21330         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
21331
21332         umount_client $MOUNT || error "failed to umount client"
21333         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
21334                 error "failed to mount client'"
21335
21336         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
21337         # rmfid should succeed
21338         cnt=$(ls -1 $DIR/$tdir | wc -l)
21339         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
21340
21341         # rmfid shouldn't allow to remove files due to dir's permission
21342         chmod a+rwx $DIR/$tdir
21343         touch $DIR/$tdir/f
21344         ls -la $DIR/$tdir
21345         FID=$(lfs path2fid $DIR/$tdir/f)
21346         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
21347
21348         umount_client $MOUNT || error "failed to umount client"
21349         mount_client $MOUNT "$MOUNT_OPTS" ||
21350                 error "failed to mount client'"
21351
21352 }
21353 run_test 421f "rmfid checks permissions"
21354
21355 test_421g() {
21356         local cnt
21357         local FIDS
21358
21359         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21360         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21361                 skip "Need MDS version at least 2.12.54"
21362
21363         mkdir -p $DIR/$tdir
21364         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21365         createmany -o $DIR/$tdir/striped_dir/f 512
21366         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21367         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21368
21369         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21370                 sed "s/[/][^:]*://g")
21371
21372         rm -f $DIR/$tdir/striped_dir/f1*
21373         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21374         removed=$((512 - cnt))
21375
21376         # few files have been just removed, so we expect
21377         # rmfid to fail on their fids
21378         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
21379         [ $removed != $errors ] && error "$errors != $removed"
21380
21381         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21382         rm -rf $DIR/$tdir
21383         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21384 }
21385 run_test 421g "rmfid to return errors properly"
21386
21387 test_422() {
21388         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
21389         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
21390         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
21391         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
21392         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
21393
21394         local amc=$(at_max_get client)
21395         local amo=$(at_max_get mds1)
21396         local timeout=`lctl get_param -n timeout`
21397
21398         at_max_set 0 client
21399         at_max_set 0 mds1
21400
21401 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
21402         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
21403                         fail_val=$(((2*timeout + 10)*1000))
21404         touch $DIR/$tdir/d3/file &
21405         sleep 2
21406 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
21407         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
21408                         fail_val=$((2*timeout + 5))
21409         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
21410         local pid=$!
21411         sleep 1
21412         kill -9 $pid
21413         sleep $((2 * timeout))
21414         echo kill $pid
21415         kill -9 $pid
21416         lctl mark touch
21417         touch $DIR/$tdir/d2/file3
21418         touch $DIR/$tdir/d2/file4
21419         touch $DIR/$tdir/d2/file5
21420
21421         wait
21422         at_max_set $amc client
21423         at_max_set $amo mds1
21424
21425         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
21426         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
21427                 error "Watchdog is always throttled"
21428 }
21429 run_test 422 "kill a process with RPC in progress"
21430
21431 prep_801() {
21432         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21433         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21434                 skip "Need server version at least 2.9.55"
21435
21436         start_full_debug_logging
21437 }
21438
21439 post_801() {
21440         stop_full_debug_logging
21441 }
21442
21443 barrier_stat() {
21444         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21445                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21446                            awk '/The barrier for/ { print $7 }')
21447                 echo $st
21448         else
21449                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
21450                 echo \'$st\'
21451         fi
21452 }
21453
21454 barrier_expired() {
21455         local expired
21456
21457         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21458                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21459                           awk '/will be expired/ { print $7 }')
21460         else
21461                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
21462         fi
21463
21464         echo $expired
21465 }
21466
21467 test_801a() {
21468         prep_801
21469
21470         echo "Start barrier_freeze at: $(date)"
21471         #define OBD_FAIL_BARRIER_DELAY          0x2202
21472         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21473         # Do not reduce barrier time - See LU-11873
21474         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
21475
21476         sleep 2
21477         local b_status=$(barrier_stat)
21478         echo "Got barrier status at: $(date)"
21479         [ "$b_status" = "'freezing_p1'" ] ||
21480                 error "(1) unexpected barrier status $b_status"
21481
21482         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21483         wait
21484         b_status=$(barrier_stat)
21485         [ "$b_status" = "'frozen'" ] ||
21486                 error "(2) unexpected barrier status $b_status"
21487
21488         local expired=$(barrier_expired)
21489         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
21490         sleep $((expired + 3))
21491
21492         b_status=$(barrier_stat)
21493         [ "$b_status" = "'expired'" ] ||
21494                 error "(3) unexpected barrier status $b_status"
21495
21496         # Do not reduce barrier time - See LU-11873
21497         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
21498                 error "(4) fail to freeze barrier"
21499
21500         b_status=$(barrier_stat)
21501         [ "$b_status" = "'frozen'" ] ||
21502                 error "(5) unexpected barrier status $b_status"
21503
21504         echo "Start barrier_thaw at: $(date)"
21505         #define OBD_FAIL_BARRIER_DELAY          0x2202
21506         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21507         do_facet mgs $LCTL barrier_thaw $FSNAME &
21508
21509         sleep 2
21510         b_status=$(barrier_stat)
21511         echo "Got barrier status at: $(date)"
21512         [ "$b_status" = "'thawing'" ] ||
21513                 error "(6) unexpected barrier status $b_status"
21514
21515         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21516         wait
21517         b_status=$(barrier_stat)
21518         [ "$b_status" = "'thawed'" ] ||
21519                 error "(7) unexpected barrier status $b_status"
21520
21521         #define OBD_FAIL_BARRIER_FAILURE        0x2203
21522         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
21523         do_facet mgs $LCTL barrier_freeze $FSNAME
21524
21525         b_status=$(barrier_stat)
21526         [ "$b_status" = "'failed'" ] ||
21527                 error "(8) unexpected barrier status $b_status"
21528
21529         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21530         do_facet mgs $LCTL barrier_thaw $FSNAME
21531
21532         post_801
21533 }
21534 run_test 801a "write barrier user interfaces and stat machine"
21535
21536 test_801b() {
21537         prep_801
21538
21539         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21540         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
21541         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
21542         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
21543         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
21544
21545         cancel_lru_locks mdc
21546
21547         # 180 seconds should be long enough
21548         do_facet mgs $LCTL barrier_freeze $FSNAME 180
21549
21550         local b_status=$(barrier_stat)
21551         [ "$b_status" = "'frozen'" ] ||
21552                 error "(6) unexpected barrier status $b_status"
21553
21554         mkdir $DIR/$tdir/d0/d10 &
21555         mkdir_pid=$!
21556
21557         touch $DIR/$tdir/d1/f13 &
21558         touch_pid=$!
21559
21560         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
21561         ln_pid=$!
21562
21563         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
21564         mv_pid=$!
21565
21566         rm -f $DIR/$tdir/d4/f12 &
21567         rm_pid=$!
21568
21569         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
21570
21571         # To guarantee taht the 'stat' is not blocked
21572         b_status=$(barrier_stat)
21573         [ "$b_status" = "'frozen'" ] ||
21574                 error "(8) unexpected barrier status $b_status"
21575
21576         # let above commands to run at background
21577         sleep 5
21578
21579         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
21580         ps -p $touch_pid || error "(10) touch should be blocked"
21581         ps -p $ln_pid || error "(11) link should be blocked"
21582         ps -p $mv_pid || error "(12) rename should be blocked"
21583         ps -p $rm_pid || error "(13) unlink should be blocked"
21584
21585         b_status=$(barrier_stat)
21586         [ "$b_status" = "'frozen'" ] ||
21587                 error "(14) unexpected barrier status $b_status"
21588
21589         do_facet mgs $LCTL barrier_thaw $FSNAME
21590         b_status=$(barrier_stat)
21591         [ "$b_status" = "'thawed'" ] ||
21592                 error "(15) unexpected barrier status $b_status"
21593
21594         wait $mkdir_pid || error "(16) mkdir should succeed"
21595         wait $touch_pid || error "(17) touch should succeed"
21596         wait $ln_pid || error "(18) link should succeed"
21597         wait $mv_pid || error "(19) rename should succeed"
21598         wait $rm_pid || error "(20) unlink should succeed"
21599
21600         post_801
21601 }
21602 run_test 801b "modification will be blocked by write barrier"
21603
21604 test_801c() {
21605         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21606
21607         prep_801
21608
21609         stop mds2 || error "(1) Fail to stop mds2"
21610
21611         do_facet mgs $LCTL barrier_freeze $FSNAME 30
21612
21613         local b_status=$(barrier_stat)
21614         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
21615                 do_facet mgs $LCTL barrier_thaw $FSNAME
21616                 error "(2) unexpected barrier status $b_status"
21617         }
21618
21619         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21620                 error "(3) Fail to rescan barrier bitmap"
21621
21622         # Do not reduce barrier time - See LU-11873
21623         do_facet mgs $LCTL barrier_freeze $FSNAME 20
21624
21625         b_status=$(barrier_stat)
21626         [ "$b_status" = "'frozen'" ] ||
21627                 error "(4) unexpected barrier status $b_status"
21628
21629         do_facet mgs $LCTL barrier_thaw $FSNAME
21630         b_status=$(barrier_stat)
21631         [ "$b_status" = "'thawed'" ] ||
21632                 error "(5) unexpected barrier status $b_status"
21633
21634         local devname=$(mdsdevname 2)
21635
21636         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
21637
21638         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21639                 error "(7) Fail to rescan barrier bitmap"
21640
21641         post_801
21642 }
21643 run_test 801c "rescan barrier bitmap"
21644
21645 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
21646 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
21647 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
21648 saved_MOUNT_OPTS=$MOUNT_OPTS
21649
21650 cleanup_802a() {
21651         trap 0
21652
21653         stopall
21654         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
21655         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
21656         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
21657         MOUNT_OPTS=$saved_MOUNT_OPTS
21658         setupall
21659 }
21660
21661 test_802a() {
21662         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
21663         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21664         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21665                 skip "Need server version at least 2.9.55"
21666
21667         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
21668
21669         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21670
21671         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21672                 error "(2) Fail to copy"
21673
21674         trap cleanup_802a EXIT
21675
21676         # sync by force before remount as readonly
21677         sync; sync_all_data; sleep 3; sync_all_data
21678
21679         stopall
21680
21681         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
21682         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
21683         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
21684
21685         echo "Mount the server as read only"
21686         setupall server_only || error "(3) Fail to start servers"
21687
21688         echo "Mount client without ro should fail"
21689         mount_client $MOUNT &&
21690                 error "(4) Mount client without 'ro' should fail"
21691
21692         echo "Mount client with ro should succeed"
21693         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
21694         mount_client $MOUNT ||
21695                 error "(5) Mount client with 'ro' should succeed"
21696
21697         echo "Modify should be refused"
21698         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21699
21700         echo "Read should be allowed"
21701         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21702                 error "(7) Read should succeed under ro mode"
21703
21704         cleanup_802a
21705 }
21706 run_test 802a "simulate readonly device"
21707
21708 test_802b() {
21709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21710         remote_mds_nodsh && skip "remote MDS with nodsh"
21711
21712         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
21713                 skip "readonly option not available"
21714
21715         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
21716
21717         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21718                 error "(2) Fail to copy"
21719
21720         # write back all cached data before setting MDT to readonly
21721         cancel_lru_locks
21722         sync_all_data
21723
21724         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
21725         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
21726
21727         echo "Modify should be refused"
21728         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21729
21730         echo "Read should be allowed"
21731         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21732                 error "(7) Read should succeed under ro mode"
21733
21734         # disable readonly
21735         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
21736 }
21737 run_test 802b "be able to set MDTs to readonly"
21738
21739 test_803() {
21740         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21741         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21742                 skip "MDS needs to be newer than 2.10.54"
21743
21744         mkdir -p $DIR/$tdir
21745         # Create some objects on all MDTs to trigger related logs objects
21746         for idx in $(seq $MDSCOUNT); do
21747                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
21748                         $DIR/$tdir/dir${idx} ||
21749                         error "Fail to create $DIR/$tdir/dir${idx}"
21750         done
21751
21752         sync; sleep 3
21753         wait_delete_completed # ensure old test cleanups are finished
21754         echo "before create:"
21755         $LFS df -i $MOUNT
21756         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21757
21758         for i in {1..10}; do
21759                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
21760                         error "Fail to create $DIR/$tdir/foo$i"
21761         done
21762
21763         sync; sleep 3
21764         echo "after create:"
21765         $LFS df -i $MOUNT
21766         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21767
21768         # allow for an llog to be cleaned up during the test
21769         [ $after_used -ge $((before_used + 10 - 1)) ] ||
21770                 error "before ($before_used) + 10 > after ($after_used)"
21771
21772         for i in {1..10}; do
21773                 rm -rf $DIR/$tdir/foo$i ||
21774                         error "Fail to remove $DIR/$tdir/foo$i"
21775         done
21776
21777         sleep 3 # avoid MDT return cached statfs
21778         wait_delete_completed
21779         echo "after unlink:"
21780         $LFS df -i $MOUNT
21781         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21782
21783         # allow for an llog to be created during the test
21784         [ $after_used -le $((before_used + 1)) ] ||
21785                 error "after ($after_used) > before ($before_used) + 1"
21786 }
21787 run_test 803 "verify agent object for remote object"
21788
21789 test_804() {
21790         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21791         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21792                 skip "MDS needs to be newer than 2.10.54"
21793         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21794
21795         mkdir -p $DIR/$tdir
21796         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
21797                 error "Fail to create $DIR/$tdir/dir0"
21798
21799         local fid=$($LFS path2fid $DIR/$tdir/dir0)
21800         local dev=$(mdsdevname 2)
21801
21802         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21803                 grep ${fid} || error "NOT found agent entry for dir0"
21804
21805         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
21806                 error "Fail to create $DIR/$tdir/dir1"
21807
21808         touch $DIR/$tdir/dir1/foo0 ||
21809                 error "Fail to create $DIR/$tdir/dir1/foo0"
21810         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
21811         local rc=0
21812
21813         for idx in $(seq $MDSCOUNT); do
21814                 dev=$(mdsdevname $idx)
21815                 do_facet mds${idx} \
21816                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21817                         grep ${fid} && rc=$idx
21818         done
21819
21820         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
21821                 error "Fail to rename foo0 to foo1"
21822         if [ $rc -eq 0 ]; then
21823                 for idx in $(seq $MDSCOUNT); do
21824                         dev=$(mdsdevname $idx)
21825                         do_facet mds${idx} \
21826                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21827                         grep ${fid} && rc=$idx
21828                 done
21829         fi
21830
21831         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
21832                 error "Fail to rename foo1 to foo2"
21833         if [ $rc -eq 0 ]; then
21834                 for idx in $(seq $MDSCOUNT); do
21835                         dev=$(mdsdevname $idx)
21836                         do_facet mds${idx} \
21837                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21838                         grep ${fid} && rc=$idx
21839                 done
21840         fi
21841
21842         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
21843
21844         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
21845                 error "Fail to link to $DIR/$tdir/dir1/foo2"
21846         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
21847                 error "Fail to rename foo2 to foo0"
21848         unlink $DIR/$tdir/dir1/foo0 ||
21849                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
21850         rm -rf $DIR/$tdir/dir0 ||
21851                 error "Fail to rm $DIR/$tdir/dir0"
21852
21853         for idx in $(seq $MDSCOUNT); do
21854                 dev=$(mdsdevname $idx)
21855                 rc=0
21856
21857                 stop mds${idx}
21858                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
21859                         rc=$?
21860                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
21861                         error "mount mds$idx failed"
21862                 df $MOUNT > /dev/null 2>&1
21863
21864                 # e2fsck should not return error
21865                 [ $rc -eq 0 ] ||
21866                         error "e2fsck detected error on MDT${idx}: rc=$rc"
21867         done
21868 }
21869 run_test 804 "verify agent entry for remote entry"
21870
21871 cleanup_805() {
21872         do_facet $SINGLEMDS zfs set quota=$old $fsset
21873         unlinkmany $DIR/$tdir/f- 1000000
21874         trap 0
21875 }
21876
21877 test_805() {
21878         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
21879         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
21880         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
21881                 skip "netfree not implemented before 0.7"
21882         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
21883                 skip "Need MDS version at least 2.10.57"
21884
21885         local fsset
21886         local freekb
21887         local usedkb
21888         local old
21889         local quota
21890         local pref="osd-zfs.lustre-MDT0000."
21891
21892         # limit available space on MDS dataset to meet nospace issue
21893         # quickly. then ZFS 0.7.2 can use reserved space if asked
21894         # properly (using netfree flag in osd_declare_destroy()
21895         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
21896         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
21897                 gawk '{print $3}')
21898         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
21899         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
21900         let "usedkb=usedkb-freekb"
21901         let "freekb=freekb/2"
21902         if let "freekb > 5000"; then
21903                 let "freekb=5000"
21904         fi
21905         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
21906         trap cleanup_805 EXIT
21907         mkdir $DIR/$tdir
21908         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
21909         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
21910         rm -rf $DIR/$tdir || error "not able to remove"
21911         do_facet $SINGLEMDS zfs set quota=$old $fsset
21912         trap 0
21913 }
21914 run_test 805 "ZFS can remove from full fs"
21915
21916 # Size-on-MDS test
21917 check_lsom_data()
21918 {
21919         local file=$1
21920         local size=$($LFS getsom -s $file)
21921         local expect=$(stat -c %s $file)
21922
21923         [[ $size == $expect ]] ||
21924                 error "$file expected size: $expect, got: $size"
21925
21926         local blocks=$($LFS getsom -b $file)
21927         expect=$(stat -c %b $file)
21928         [[ $blocks == $expect ]] ||
21929                 error "$file expected blocks: $expect, got: $blocks"
21930 }
21931
21932 check_lsom_size()
21933 {
21934         local size=$($LFS getsom -s $1)
21935         local expect=$2
21936
21937         [[ $size == $expect ]] ||
21938                 error "$file expected size: $expect, got: $size"
21939 }
21940
21941 test_806() {
21942         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21943                 skip "Need MDS version at least 2.11.52"
21944
21945         local bs=1048576
21946
21947         touch $DIR/$tfile || error "touch $tfile failed"
21948
21949         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21950         save_lustre_params client "llite.*.xattr_cache" > $save
21951         lctl set_param llite.*.xattr_cache=0
21952         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21953
21954         # single-threaded write
21955         echo "Test SOM for single-threaded write"
21956         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
21957                 error "write $tfile failed"
21958         check_lsom_size $DIR/$tfile $bs
21959
21960         local num=32
21961         local size=$(($num * $bs))
21962         local offset=0
21963         local i
21964
21965         echo "Test SOM for single client multi-threaded($num) write"
21966         $TRUNCATE $DIR/$tfile 0
21967         for ((i = 0; i < $num; i++)); do
21968                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21969                 local pids[$i]=$!
21970                 offset=$((offset + $bs))
21971         done
21972         for (( i=0; i < $num; i++ )); do
21973                 wait ${pids[$i]}
21974         done
21975         check_lsom_size $DIR/$tfile $size
21976
21977         $TRUNCATE $DIR/$tfile 0
21978         for ((i = 0; i < $num; i++)); do
21979                 offset=$((offset - $bs))
21980                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21981                 local pids[$i]=$!
21982         done
21983         for (( i=0; i < $num; i++ )); do
21984                 wait ${pids[$i]}
21985         done
21986         check_lsom_size $DIR/$tfile $size
21987
21988         # multi-client writes
21989         num=$(get_node_count ${CLIENTS//,/ })
21990         size=$(($num * $bs))
21991         offset=0
21992         i=0
21993
21994         echo "Test SOM for multi-client ($num) writes"
21995         $TRUNCATE $DIR/$tfile 0
21996         for client in ${CLIENTS//,/ }; do
21997                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21998                 local pids[$i]=$!
21999                 i=$((i + 1))
22000                 offset=$((offset + $bs))
22001         done
22002         for (( i=0; i < $num; i++ )); do
22003                 wait ${pids[$i]}
22004         done
22005         check_lsom_size $DIR/$tfile $offset
22006
22007         i=0
22008         $TRUNCATE $DIR/$tfile 0
22009         for client in ${CLIENTS//,/ }; do
22010                 offset=$((offset - $bs))
22011                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22012                 local pids[$i]=$!
22013                 i=$((i + 1))
22014         done
22015         for (( i=0; i < $num; i++ )); do
22016                 wait ${pids[$i]}
22017         done
22018         check_lsom_size $DIR/$tfile $size
22019
22020         # verify truncate
22021         echo "Test SOM for truncate"
22022         $TRUNCATE $DIR/$tfile 1048576
22023         check_lsom_size $DIR/$tfile 1048576
22024         $TRUNCATE $DIR/$tfile 1234
22025         check_lsom_size $DIR/$tfile 1234
22026
22027         # verify SOM blocks count
22028         echo "Verify SOM block count"
22029         $TRUNCATE $DIR/$tfile 0
22030         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
22031                 error "failed to write file $tfile"
22032         check_lsom_data $DIR/$tfile
22033 }
22034 run_test 806 "Verify Lazy Size on MDS"
22035
22036 test_807() {
22037         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22038         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22039                 skip "Need MDS version at least 2.11.52"
22040
22041         # Registration step
22042         changelog_register || error "changelog_register failed"
22043         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
22044         changelog_users $SINGLEMDS | grep -q $cl_user ||
22045                 error "User $cl_user not found in changelog_users"
22046
22047         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22048         save_lustre_params client "llite.*.xattr_cache" > $save
22049         lctl set_param llite.*.xattr_cache=0
22050         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22051
22052         rm -rf $DIR/$tdir || error "rm $tdir failed"
22053         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22054         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
22055         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
22056         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
22057                 error "truncate $tdir/trunc failed"
22058
22059         local bs=1048576
22060         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
22061                 error "write $tfile failed"
22062
22063         # multi-client wirtes
22064         local num=$(get_node_count ${CLIENTS//,/ })
22065         local offset=0
22066         local i=0
22067
22068         echo "Test SOM for multi-client ($num) writes"
22069         touch $DIR/$tfile || error "touch $tfile failed"
22070         $TRUNCATE $DIR/$tfile 0
22071         for client in ${CLIENTS//,/ }; do
22072                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22073                 local pids[$i]=$!
22074                 i=$((i + 1))
22075                 offset=$((offset + $bs))
22076         done
22077         for (( i=0; i < $num; i++ )); do
22078                 wait ${pids[$i]}
22079         done
22080
22081         sleep 5
22082         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
22083         check_lsom_data $DIR/$tdir/trunc
22084         check_lsom_data $DIR/$tdir/single_dd
22085         check_lsom_data $DIR/$tfile
22086
22087         rm -rf $DIR/$tdir
22088         # Deregistration step
22089         changelog_deregister || error "changelog_deregister failed"
22090 }
22091 run_test 807 "verify LSOM syncing tool"
22092
22093 check_som_nologged()
22094 {
22095         local lines=$($LFS changelog $FSNAME-MDT0000 |
22096                 grep 'x=trusted.som' | wc -l)
22097         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
22098 }
22099
22100 test_808() {
22101         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22102                 skip "Need MDS version at least 2.11.55"
22103
22104         # Registration step
22105         changelog_register || error "changelog_register failed"
22106
22107         touch $DIR/$tfile || error "touch $tfile failed"
22108         check_som_nologged
22109
22110         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
22111                 error "write $tfile failed"
22112         check_som_nologged
22113
22114         $TRUNCATE $DIR/$tfile 1234
22115         check_som_nologged
22116
22117         $TRUNCATE $DIR/$tfile 1048576
22118         check_som_nologged
22119
22120         # Deregistration step
22121         changelog_deregister || error "changelog_deregister failed"
22122 }
22123 run_test 808 "Check trusted.som xattr not logged in Changelogs"
22124
22125 check_som_nodata()
22126 {
22127         $LFS getsom $1
22128         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
22129 }
22130
22131 test_809() {
22132         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22133                 skip "Need MDS version at least 2.11.56"
22134
22135         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
22136                 error "failed to create DoM-only file $DIR/$tfile"
22137         touch $DIR/$tfile || error "touch $tfile failed"
22138         check_som_nodata $DIR/$tfile
22139
22140         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
22141                 error "write $tfile failed"
22142         check_som_nodata $DIR/$tfile
22143
22144         $TRUNCATE $DIR/$tfile 1234
22145         check_som_nodata $DIR/$tfile
22146
22147         $TRUNCATE $DIR/$tfile 4097
22148         check_som_nodata $DIR/$file
22149 }
22150 run_test 809 "Verify no SOM xattr store for DoM-only files"
22151
22152 test_810() {
22153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22154         $GSS && skip_env "could not run with gss"
22155         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
22156                 skip "OST < 2.12.58 doesn't align checksum"
22157
22158         set_checksums 1
22159         stack_trap "set_checksums $ORIG_CSUM" EXIT
22160         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
22161
22162         local csum
22163         local before
22164         local after
22165         for csum in $CKSUM_TYPES; do
22166                 #define OBD_FAIL_OSC_NO_GRANT   0x411
22167                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
22168                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
22169                         eval set -- $i
22170                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
22171                         before=$(md5sum $DIR/$tfile)
22172                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
22173                         after=$(md5sum $DIR/$tfile)
22174                         [ "$before" == "$after" ] ||
22175                                 error "$csum: $before != $after bs=$1 seek=$2"
22176                 done
22177         done
22178 }
22179 run_test 810 "partial page writes on ZFS (LU-11663)"
22180
22181 test_811() {
22182         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
22183                 skip "Need MDS version at least 2.11.56"
22184
22185         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
22186         do_facet mds1 $LCTL set_param fail_loc=0x165
22187         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
22188
22189         stop mds1
22190         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22191
22192         sleep 5
22193         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
22194                 error "MDD orphan cleanup thread not quit"
22195 }
22196 run_test 811 "orphan name stub can be cleaned up in startup"
22197
22198 test_812() {
22199         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
22200                 skip "OST < 2.12.51 doesn't support this fail_loc"
22201         [ "$SHARED_KEY" = true ] &&
22202                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22203
22204         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22205         # ensure ost1 is connected
22206         stat $DIR/$tfile >/dev/null || error "can't stat"
22207         wait_osc_import_state client ost1 FULL
22208         # no locks, no reqs to let the connection idle
22209         cancel_lru_locks osc
22210
22211         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
22212 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
22213         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
22214         wait_osc_import_state client ost1 CONNECTING
22215         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
22216
22217         stat $DIR/$tfile >/dev/null || error "can't stat file"
22218 }
22219 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
22220
22221 test_813() {
22222         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
22223         [ -z "$file_heat_sav" ] && skip "no file heat support"
22224
22225         local readsample
22226         local writesample
22227         local readbyte
22228         local writebyte
22229         local readsample1
22230         local writesample1
22231         local readbyte1
22232         local writebyte1
22233
22234         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
22235         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
22236
22237         $LCTL set_param -n llite.*.file_heat=1
22238         echo "Turn on file heat"
22239         echo "Period second: $period_second, Decay percentage: $decay_pct"
22240
22241         echo "QQQQ" > $DIR/$tfile
22242         echo "QQQQ" > $DIR/$tfile
22243         echo "QQQQ" > $DIR/$tfile
22244         cat $DIR/$tfile > /dev/null
22245         cat $DIR/$tfile > /dev/null
22246         cat $DIR/$tfile > /dev/null
22247         cat $DIR/$tfile > /dev/null
22248
22249         local out=$($LFS heat_get $DIR/$tfile)
22250
22251         $LFS heat_get $DIR/$tfile
22252         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22253         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22254         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22255         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22256
22257         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
22258         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
22259         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
22260         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
22261
22262         sleep $((period_second + 3))
22263         echo "Sleep $((period_second + 3)) seconds..."
22264         # The recursion formula to calculate the heat of the file f is as
22265         # follow:
22266         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
22267         # Where Hi is the heat value in the period between time points i*I and
22268         # (i+1)*I; Ci is the access count in the period; the symbol P refers
22269         # to the weight of Ci.
22270         out=$($LFS heat_get $DIR/$tfile)
22271         $LFS heat_get $DIR/$tfile
22272         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22273         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22274         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22275         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22276
22277         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
22278                 error "read sample ($readsample) is wrong"
22279         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
22280                 error "write sample ($writesample) is wrong"
22281         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
22282                 error "read bytes ($readbyte) is wrong"
22283         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
22284                 error "write bytes ($writebyte) is wrong"
22285
22286         echo "QQQQ" > $DIR/$tfile
22287         echo "QQQQ" > $DIR/$tfile
22288         echo "QQQQ" > $DIR/$tfile
22289         cat $DIR/$tfile > /dev/null
22290         cat $DIR/$tfile > /dev/null
22291         cat $DIR/$tfile > /dev/null
22292         cat $DIR/$tfile > /dev/null
22293
22294         sleep $((period_second + 3))
22295         echo "Sleep $((period_second + 3)) seconds..."
22296
22297         out=$($LFS heat_get $DIR/$tfile)
22298         $LFS heat_get $DIR/$tfile
22299         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22300         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22301         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22302         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22303
22304         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
22305                 4 * $decay_pct) / 100") -eq 1 ] ||
22306                 error "read sample ($readsample1) is wrong"
22307         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
22308                 3 * $decay_pct) / 100") -eq 1 ] ||
22309                 error "write sample ($writesample1) is wrong"
22310         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
22311                 20 * $decay_pct) / 100") -eq 1 ] ||
22312                 error "read bytes ($readbyte1) is wrong"
22313         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
22314                 15 * $decay_pct) / 100") -eq 1 ] ||
22315                 error "write bytes ($writebyte1) is wrong"
22316
22317         echo "Turn off file heat for the file $DIR/$tfile"
22318         $LFS heat_set -o $DIR/$tfile
22319
22320         echo "QQQQ" > $DIR/$tfile
22321         echo "QQQQ" > $DIR/$tfile
22322         echo "QQQQ" > $DIR/$tfile
22323         cat $DIR/$tfile > /dev/null
22324         cat $DIR/$tfile > /dev/null
22325         cat $DIR/$tfile > /dev/null
22326         cat $DIR/$tfile > /dev/null
22327
22328         out=$($LFS heat_get $DIR/$tfile)
22329         $LFS heat_get $DIR/$tfile
22330         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22331         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22332         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22333         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22334
22335         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22336         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22337         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22338         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22339
22340         echo "Trun on file heat for the file $DIR/$tfile"
22341         $LFS heat_set -O $DIR/$tfile
22342
22343         echo "QQQQ" > $DIR/$tfile
22344         echo "QQQQ" > $DIR/$tfile
22345         echo "QQQQ" > $DIR/$tfile
22346         cat $DIR/$tfile > /dev/null
22347         cat $DIR/$tfile > /dev/null
22348         cat $DIR/$tfile > /dev/null
22349         cat $DIR/$tfile > /dev/null
22350
22351         out=$($LFS heat_get $DIR/$tfile)
22352         $LFS heat_get $DIR/$tfile
22353         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22354         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22355         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22356         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22357
22358         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
22359         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
22360         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
22361         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
22362
22363         $LFS heat_set -c $DIR/$tfile
22364         $LCTL set_param -n llite.*.file_heat=0
22365         echo "Turn off file heat support for the Lustre filesystem"
22366
22367         echo "QQQQ" > $DIR/$tfile
22368         echo "QQQQ" > $DIR/$tfile
22369         echo "QQQQ" > $DIR/$tfile
22370         cat $DIR/$tfile > /dev/null
22371         cat $DIR/$tfile > /dev/null
22372         cat $DIR/$tfile > /dev/null
22373         cat $DIR/$tfile > /dev/null
22374
22375         out=$($LFS heat_get $DIR/$tfile)
22376         $LFS heat_get $DIR/$tfile
22377         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22378         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22379         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22380         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22381
22382         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22383         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22384         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22385         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22386
22387         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
22388         rm -f $DIR/$tfile
22389 }
22390 run_test 813 "File heat verfication"
22391
22392 test_814()
22393 {
22394         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
22395         echo -n y >> $DIR/$tfile
22396         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
22397         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
22398 }
22399 run_test 814 "sparse cp works as expected (LU-12361)"
22400
22401 test_815()
22402 {
22403         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
22404         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
22405 }
22406 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
22407
22408 test_816() {
22409         [ "$SHARED_KEY" = true ] &&
22410                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22411
22412         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22413         # ensure ost1 is connected
22414         stat $DIR/$tfile >/dev/null || error "can't stat"
22415         wait_osc_import_state client ost1 FULL
22416         # no locks, no reqs to let the connection idle
22417         cancel_lru_locks osc
22418         lru_resize_disable osc
22419         local before
22420         local now
22421         before=$($LCTL get_param -n \
22422                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22423
22424         wait_osc_import_state client ost1 IDLE
22425         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
22426         now=$($LCTL get_param -n \
22427               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22428         [ $before == $now ] || error "lru_size changed $before != $now"
22429 }
22430 run_test 816 "do not reset lru_resize on idle reconnect"
22431
22432 cleanup_817() {
22433         umount $tmpdir
22434         exportfs -u localhost:$DIR/nfsexp
22435         rm -rf $DIR/nfsexp
22436 }
22437
22438 test_817() {
22439         systemctl restart nfs-server.service || skip "failed to restart nfsd"
22440
22441         mkdir -p $DIR/nfsexp
22442         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
22443                 error "failed to export nfs"
22444
22445         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
22446         stack_trap cleanup_817 EXIT
22447
22448         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
22449                 error "failed to mount nfs to $tmpdir"
22450
22451         cp /bin/true $tmpdir
22452         $DIR/nfsexp/true || error "failed to execute 'true' command"
22453 }
22454 run_test 817 "nfsd won't cache write lock for exec file"
22455
22456 test_818() {
22457         mkdir $DIR/$tdir
22458         $LFS setstripe -c1 -i0 $DIR/$tfile
22459         $LFS setstripe -c1 -i1 $DIR/$tfile
22460         stop $SINGLEMDS
22461         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
22462         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
22463         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
22464                 error "start $SINGLEMDS failed"
22465         rm -rf $DIR/$tdir
22466 }
22467 run_test 818 "unlink with failed llog"
22468
22469 test_819a() {
22470         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22471         cancel_lru_locks osc
22472         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22473         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22474         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
22475         rm -f $TDIR/$tfile
22476 }
22477 run_test 819a "too big niobuf in read"
22478
22479 test_819b() {
22480         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22481         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22482         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22483         cancel_lru_locks osc
22484         sleep 1
22485         rm -f $TDIR/$tfile
22486 }
22487 run_test 819b "too big niobuf in write"
22488
22489 #
22490 # tests that do cleanup/setup should be run at the end
22491 #
22492
22493 test_900() {
22494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22495         local ls
22496
22497         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
22498         $LCTL set_param fail_loc=0x903
22499
22500         cancel_lru_locks MGC
22501
22502         FAIL_ON_ERROR=true cleanup
22503         FAIL_ON_ERROR=true setup
22504 }
22505 run_test 900 "umount should not race with any mgc requeue thread"
22506
22507 complete $SECONDS
22508 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
22509 check_and_cleanup_lustre
22510 if [ "$I_MOUNTED" != "yes" ]; then
22511         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
22512 fi
22513 exit_status