Whamcloud - gitweb
LU-12838 ptlrpc: fix watchdog ratelimit logic
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 LUSTRE=${LUSTRE:-$(dirname $0)/..}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312 "
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f "
50 fi
51
52 # skip the grant tests for ARM until they are fixed
53 if [[ $(uname -m) = aarch64 ]]; then
54         # bug number:    LU-11596
55         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
56         # bug number:    LU-11671 LU-11667 LU-4398
57         ALWAYS_EXCEPT+=" 45       317      817"
58 fi
59
60 #                                  5          12          (min)"
61 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
62
63 if [ "$mds1_FSTYPE" = "zfs" ]; then
64         # bug number for skipped test:
65         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
66         #                                               13    (min)"
67         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
68 fi
69
70 # Get the SLES distro version
71 #
72 # Returns a version string that should only be used in comparing
73 # strings returned by version_code()
74 sles_version_code()
75 {
76         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
77
78         # All SuSE Linux versions have one decimal. version_code expects two
79         local sles_version=$version.0
80         version_code $sles_version
81 }
82
83 # Check if we are running on Ubuntu or SLES so we can make decisions on
84 # what tests to run
85 if [ -r /etc/SuSE-release ]; then
86         sles_version=$(sles_version_code)
87         [ $sles_version -lt $(version_code 11.4.0) ] &&
88                 # bug number for skipped test: LU-4341
89                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
90         [ $sles_version -lt $(version_code 12.0.0) ] &&
91                 # bug number for skipped test: LU-3703
92                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
93 elif [ -r /etc/os-release ]; then
94         if grep -qi ubuntu /etc/os-release; then
95                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
96                                                 -e 's/^VERSION=//p' \
97                                                 /etc/os-release |
98                                                 awk '{ print $1 }'))
99
100                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
101                         # bug number for skipped test:
102                         #                LU-10334 LU-10366
103                         ALWAYS_EXCEPT+=" 103a     410"
104                 fi
105         fi
106 fi
107
108 build_test_filter
109 FAIL_ON_ERROR=false
110
111 cleanup() {
112         echo -n "cln.."
113         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
114         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
115 }
116 setup() {
117         echo -n "mnt.."
118         load_modules
119         setupall || exit 10
120         echo "done"
121 }
122
123 check_swap_layouts_support()
124 {
125         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
126                 skip "Does not support layout lock."
127 }
128
129 check_and_setup_lustre
130 DIR=${DIR:-$MOUNT}
131 assert_DIR
132
133 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
134
135 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
136 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
137 rm -rf $DIR/[Rdfs][0-9]*
138
139 # $RUNAS_ID may get set incorrectly somewhere else
140 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
141         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
142
143 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
144
145 if [ "${ONLY}" = "MOUNT" ] ; then
146         echo "Lustre is up, please go on"
147         exit
148 fi
149
150 echo "preparing for tests involving mounts"
151 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
152 touch $EXT2_DEV
153 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
154 echo # add a newline after mke2fs.
155
156 umask 077
157
158 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
159 lctl set_param debug=-1 2> /dev/null || true
160 test_0a() {
161         touch $DIR/$tfile
162         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
163         rm $DIR/$tfile
164         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
165 }
166 run_test 0a "touch; rm ====================="
167
168 test_0b() {
169         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
170         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
171 }
172 run_test 0b "chmod 0755 $DIR ============================="
173
174 test_0c() {
175         $LCTL get_param mdc.*.import | grep "state: FULL" ||
176                 error "import not FULL"
177         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
178                 error "bad target"
179 }
180 run_test 0c "check import proc"
181
182 test_0d() { # LU-3397
183         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
184                 skip "proc exports not supported before 2.10.57"
185
186         local mgs_exp="mgs.MGS.exports"
187         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
188         local exp_client_nid
189         local exp_client_version
190         local exp_val
191         local imp_val
192         local temp_imp=$DIR/$tfile.import
193         local temp_exp=$DIR/$tfile.export
194
195         # save mgc import file to $temp_imp
196         $LCTL get_param mgc.*.import | tee $temp_imp
197         # Check if client uuid is found in MGS export
198         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
199                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
200                         $client_uuid ] &&
201                         break;
202         done
203         # save mgs export file to $temp_exp
204         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
205
206         # Compare the value of field "connect_flags"
207         imp_val=$(grep "connect_flags" $temp_imp)
208         exp_val=$(grep "connect_flags" $temp_exp)
209         [ "$exp_val" == "$imp_val" ] ||
210                 error "export flags '$exp_val' != import flags '$imp_val'"
211
212         # Compare the value of client version
213         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
214         exp_val=$(version_code $exp_client_version)
215         imp_val=$CLIENT_VERSION
216         [ "$exp_val" == "$imp_val" ] ||
217                 error "export client version '$exp_val' != '$imp_val'"
218 }
219 run_test 0d "check export proc ============================="
220
221 test_1() {
222         test_mkdir $DIR/$tdir
223         test_mkdir $DIR/$tdir/d2
224         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
225         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
226         rmdir $DIR/$tdir/d2
227         rmdir $DIR/$tdir
228         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
229 }
230 run_test 1 "mkdir; remkdir; rmdir"
231
232 test_2() {
233         test_mkdir $DIR/$tdir
234         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
235         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
236         rm -r $DIR/$tdir
237         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
238 }
239 run_test 2 "mkdir; touch; rmdir; check file"
240
241 test_3() {
242         test_mkdir $DIR/$tdir
243         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
244         touch $DIR/$tdir/$tfile
245         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
246         rm -r $DIR/$tdir
247         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
248 }
249 run_test 3 "mkdir; touch; rmdir; check dir"
250
251 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
252 test_4() {
253         test_mkdir -i 1 $DIR/$tdir
254
255         touch $DIR/$tdir/$tfile ||
256                 error "Create file under remote directory failed"
257
258         rmdir $DIR/$tdir &&
259                 error "Expect error removing in-use dir $DIR/$tdir"
260
261         test -d $DIR/$tdir || error "Remote directory disappeared"
262
263         rm -rf $DIR/$tdir || error "remove remote dir error"
264 }
265 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
266
267 test_5() {
268         test_mkdir $DIR/$tdir
269         test_mkdir $DIR/$tdir/d2
270         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
271         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
272         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
273 }
274 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
275
276 test_6a() {
277         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
278         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
279         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
280                 error "$tfile does not have perm 0666 or UID $UID"
281         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
282         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
283                 error "$tfile should be 0666 and owned by UID $UID"
284 }
285 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
286
287 test_6c() {
288         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
289
290         touch $DIR/$tfile
291         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
292         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
293                 error "$tfile should be owned by UID $RUNAS_ID"
294         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
295         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
296                 error "$tfile should be owned by UID $RUNAS_ID"
297 }
298 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
299
300 test_6e() {
301         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
302
303         touch $DIR/$tfile
304         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
305         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
306                 error "$tfile should be owned by GID $UID"
307         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
308         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
309                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
310 }
311 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
312
313 test_6g() {
314         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
315
316         test_mkdir $DIR/$tdir
317         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
318         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
319         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
320         test_mkdir $DIR/$tdir/d/subdir
321         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
322                 error "$tdir/d/subdir should be GID $RUNAS_GID"
323         if [[ $MDSCOUNT -gt 1 ]]; then
324                 # check remote dir sgid inherite
325                 $LFS mkdir -i 0 $DIR/$tdir.local ||
326                         error "mkdir $tdir.local failed"
327                 chmod g+s $DIR/$tdir.local ||
328                         error "chmod $tdir.local failed"
329                 chgrp $RUNAS_GID $DIR/$tdir.local ||
330                         error "chgrp $tdir.local failed"
331                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
332                         error "mkdir $tdir.remote failed"
333                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
334                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
335                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
336                         error "$tdir.remote should be mode 02755"
337         fi
338 }
339 run_test 6g "verify new dir in sgid dir inherits group"
340
341 test_6h() { # bug 7331
342         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
343
344         touch $DIR/$tfile || error "touch failed"
345         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
346         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
347                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
348         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
349                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
350 }
351 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
352
353 test_7a() {
354         test_mkdir $DIR/$tdir
355         $MCREATE $DIR/$tdir/$tfile
356         chmod 0666 $DIR/$tdir/$tfile
357         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
358                 error "$tdir/$tfile should be mode 0666"
359 }
360 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
361
362 test_7b() {
363         if [ ! -d $DIR/$tdir ]; then
364                 test_mkdir $DIR/$tdir
365         fi
366         $MCREATE $DIR/$tdir/$tfile
367         echo -n foo > $DIR/$tdir/$tfile
368         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
369         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
370 }
371 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
372
373 test_8() {
374         test_mkdir $DIR/$tdir
375         touch $DIR/$tdir/$tfile
376         chmod 0666 $DIR/$tdir/$tfile
377         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
378                 error "$tfile mode not 0666"
379 }
380 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
381
382 test_9() {
383         test_mkdir $DIR/$tdir
384         test_mkdir $DIR/$tdir/d2
385         test_mkdir $DIR/$tdir/d2/d3
386         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
387 }
388 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
389
390 test_10() {
391         test_mkdir $DIR/$tdir
392         test_mkdir $DIR/$tdir/d2
393         touch $DIR/$tdir/d2/$tfile
394         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
395                 error "$tdir/d2/$tfile not a file"
396 }
397 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
398
399 test_11() {
400         test_mkdir $DIR/$tdir
401         test_mkdir $DIR/$tdir/d2
402         chmod 0666 $DIR/$tdir/d2
403         chmod 0705 $DIR/$tdir/d2
404         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
405                 error "$tdir/d2 mode not 0705"
406 }
407 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
408
409 test_12() {
410         test_mkdir $DIR/$tdir
411         touch $DIR/$tdir/$tfile
412         chmod 0666 $DIR/$tdir/$tfile
413         chmod 0654 $DIR/$tdir/$tfile
414         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
415                 error "$tdir/d2 mode not 0654"
416 }
417 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
418
419 test_13() {
420         test_mkdir $DIR/$tdir
421         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
422         >  $DIR/$tdir/$tfile
423         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
424                 error "$tdir/$tfile size not 0 after truncate"
425 }
426 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
427
428 test_14() {
429         test_mkdir $DIR/$tdir
430         touch $DIR/$tdir/$tfile
431         rm $DIR/$tdir/$tfile
432         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
433 }
434 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
435
436 test_15() {
437         test_mkdir $DIR/$tdir
438         touch $DIR/$tdir/$tfile
439         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
440         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
441                 error "$tdir/${tfile_2} not a file after rename"
442         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
443 }
444 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
445
446 test_16() {
447         test_mkdir $DIR/$tdir
448         touch $DIR/$tdir/$tfile
449         rm -rf $DIR/$tdir/$tfile
450         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
451 }
452 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
453
454 test_17a() {
455         test_mkdir $DIR/$tdir
456         touch $DIR/$tdir/$tfile
457         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
458         ls -l $DIR/$tdir
459         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
460                 error "$tdir/l-exist not a symlink"
461         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
462                 error "$tdir/l-exist not referencing a file"
463         rm -f $DIR/$tdir/l-exist
464         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
465 }
466 run_test 17a "symlinks: create, remove (real)"
467
468 test_17b() {
469         test_mkdir $DIR/$tdir
470         ln -s no-such-file $DIR/$tdir/l-dangle
471         ls -l $DIR/$tdir
472         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
473                 error "$tdir/l-dangle not referencing no-such-file"
474         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
475                 error "$tdir/l-dangle not referencing non-existent file"
476         rm -f $DIR/$tdir/l-dangle
477         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
478 }
479 run_test 17b "symlinks: create, remove (dangling)"
480
481 test_17c() { # bug 3440 - don't save failed open RPC for replay
482         test_mkdir $DIR/$tdir
483         ln -s foo $DIR/$tdir/$tfile
484         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
485 }
486 run_test 17c "symlinks: open dangling (should return error)"
487
488 test_17d() {
489         test_mkdir $DIR/$tdir
490         ln -s foo $DIR/$tdir/$tfile
491         touch $DIR/$tdir/$tfile || error "creating to new symlink"
492 }
493 run_test 17d "symlinks: create dangling"
494
495 test_17e() {
496         test_mkdir $DIR/$tdir
497         local foo=$DIR/$tdir/$tfile
498         ln -s $foo $foo || error "create symlink failed"
499         ls -l $foo || error "ls -l failed"
500         ls $foo && error "ls not failed" || true
501 }
502 run_test 17e "symlinks: create recursive symlink (should return error)"
503
504 test_17f() {
505         test_mkdir $DIR/$tdir
506         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
507         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
508         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
509         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
510         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
511         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
512         ls -l  $DIR/$tdir
513 }
514 run_test 17f "symlinks: long and very long symlink name"
515
516 # str_repeat(S, N) generate a string that is string S repeated N times
517 str_repeat() {
518         local s=$1
519         local n=$2
520         local ret=''
521         while [ $((n -= 1)) -ge 0 ]; do
522                 ret=$ret$s
523         done
524         echo $ret
525 }
526
527 # Long symlinks and LU-2241
528 test_17g() {
529         test_mkdir $DIR/$tdir
530         local TESTS="59 60 61 4094 4095"
531
532         # Fix for inode size boundary in 2.1.4
533         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
534                 TESTS="4094 4095"
535
536         # Patch not applied to 2.2 or 2.3 branches
537         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
538         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
539                 TESTS="4094 4095"
540
541         # skip long symlink name for rhel6.5.
542         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
543         grep -q '6.5' /etc/redhat-release &>/dev/null &&
544                 TESTS="59 60 61 4062 4063"
545
546         for i in $TESTS; do
547                 local SYMNAME=$(str_repeat 'x' $i)
548                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
549                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
550         done
551 }
552 run_test 17g "symlinks: really long symlink name and inode boundaries"
553
554 test_17h() { #bug 17378
555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
556         remote_mds_nodsh && skip "remote MDS with nodsh"
557
558         local mdt_idx
559
560         test_mkdir $DIR/$tdir
561         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
562         $LFS setstripe -c -1 $DIR/$tdir
563         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
564         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
565         touch $DIR/$tdir/$tfile || true
566 }
567 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
568
569 test_17i() { #bug 20018
570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
571         remote_mds_nodsh && skip "remote MDS with nodsh"
572
573         local foo=$DIR/$tdir/$tfile
574         local mdt_idx
575
576         test_mkdir -c1 $DIR/$tdir
577         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
578         ln -s $foo $foo || error "create symlink failed"
579 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
580         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
581         ls -l $foo && error "error not detected"
582         return 0
583 }
584 run_test 17i "don't panic on short symlink (should return error)"
585
586 test_17k() { #bug 22301
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         [[ -z "$(which rsync 2>/dev/null)" ]] &&
589                 skip "no rsync command"
590         rsync --help | grep -q xattr ||
591                 skip_env "$(rsync --version | head -n1) does not support xattrs"
592         test_mkdir $DIR/$tdir
593         test_mkdir $DIR/$tdir.new
594         touch $DIR/$tdir/$tfile
595         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
596         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
597                 error "rsync failed with xattrs enabled"
598 }
599 run_test 17k "symlinks: rsync with xattrs enabled"
600
601 test_17l() { # LU-279
602         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
603                 skip "no getfattr command"
604
605         test_mkdir $DIR/$tdir
606         touch $DIR/$tdir/$tfile
607         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
608         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
609                 # -h to not follow symlinks. -m '' to list all the xattrs.
610                 # grep to remove first line: '# file: $path'.
611                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
612                 do
613                         lgetxattr_size_check $path $xattr ||
614                                 error "lgetxattr_size_check $path $xattr failed"
615                 done
616         done
617 }
618 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
619
620 # LU-1540
621 test_17m() {
622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
623         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
624         remote_mds_nodsh && skip "remote MDS with nodsh"
625         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
626         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
627                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
628
629         local short_sym="0123456789"
630         local wdir=$DIR/$tdir
631         local i
632
633         test_mkdir $wdir
634         long_sym=$short_sym
635         # create a long symlink file
636         for ((i = 0; i < 4; ++i)); do
637                 long_sym=${long_sym}${long_sym}
638         done
639
640         echo "create 512 short and long symlink files under $wdir"
641         for ((i = 0; i < 256; ++i)); do
642                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
643                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
644         done
645
646         echo "erase them"
647         rm -f $wdir/*
648         sync
649         wait_delete_completed
650
651         echo "recreate the 512 symlink files with a shorter string"
652         for ((i = 0; i < 512; ++i)); do
653                 # rewrite the symlink file with a shorter string
654                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
655                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
656         done
657
658         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
659         local devname=$(mdsdevname $mds_index)
660
661         echo "stop and checking mds${mds_index}:"
662         # e2fsck should not return error
663         stop mds${mds_index}
664         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
665         rc=$?
666
667         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
668                 error "start mds${mds_index} failed"
669         df $MOUNT > /dev/null 2>&1
670         [ $rc -eq 0 ] ||
671                 error "e2fsck detected error for short/long symlink: rc=$rc"
672         rm -f $wdir/*
673 }
674 run_test 17m "run e2fsck against MDT which contains short/long symlink"
675
676 check_fs_consistency_17n() {
677         local mdt_index
678         local rc=0
679
680         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
681         # so it only check MDT1/MDT2 instead of all of MDTs.
682         for mdt_index in 1 2; do
683                 local devname=$(mdsdevname $mdt_index)
684                 # e2fsck should not return error
685                 stop mds${mdt_index}
686                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
687                         rc=$((rc + $?))
688
689                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
690                         error "mount mds$mdt_index failed"
691                 df $MOUNT > /dev/null 2>&1
692         done
693         return $rc
694 }
695
696 test_17n() {
697         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
699         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
700         remote_mds_nodsh && skip "remote MDS with nodsh"
701         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
702         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
703                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
704
705         local i
706
707         test_mkdir $DIR/$tdir
708         for ((i=0; i<10; i++)); do
709                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
710                         error "create remote dir error $i"
711                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
712                         error "create files under remote dir failed $i"
713         done
714
715         check_fs_consistency_17n ||
716                 error "e2fsck report error after create files under remote dir"
717
718         for ((i = 0; i < 10; i++)); do
719                 rm -rf $DIR/$tdir/remote_dir_${i} ||
720                         error "destroy remote dir error $i"
721         done
722
723         check_fs_consistency_17n ||
724                 error "e2fsck report error after unlink files under remote dir"
725
726         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
727                 skip "lustre < 2.4.50 does not support migrate mv"
728
729         for ((i = 0; i < 10; i++)); do
730                 mkdir -p $DIR/$tdir/remote_dir_${i}
731                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
732                         error "create files under remote dir failed $i"
733                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
734                         error "migrate remote dir error $i"
735         done
736         check_fs_consistency_17n || error "e2fsck report error after migration"
737
738         for ((i = 0; i < 10; i++)); do
739                 rm -rf $DIR/$tdir/remote_dir_${i} ||
740                         error "destroy remote dir error $i"
741         done
742
743         check_fs_consistency_17n || error "e2fsck report error after unlink"
744 }
745 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
746
747 test_17o() {
748         remote_mds_nodsh && skip "remote MDS with nodsh"
749         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
750                 skip "Need MDS version at least 2.3.64"
751
752         local wdir=$DIR/${tdir}o
753         local mdt_index
754         local rc=0
755
756         test_mkdir $wdir
757         touch $wdir/$tfile
758         mdt_index=$($LFS getstripe -m $wdir/$tfile)
759         mdt_index=$((mdt_index + 1))
760
761         cancel_lru_locks mdc
762         #fail mds will wait the failover finish then set
763         #following fail_loc to avoid interfer the recovery process.
764         fail mds${mdt_index}
765
766         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
767         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
768         ls -l $wdir/$tfile && rc=1
769         do_facet mds${mdt_index} lctl set_param fail_loc=0
770         [[ $rc -eq 0 ]] || error "stat file should fail"
771 }
772 run_test 17o "stat file with incompat LMA feature"
773
774 test_18() {
775         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
776         ls $DIR || error "Failed to ls $DIR: $?"
777 }
778 run_test 18 "touch .../f ; ls ... =============================="
779
780 test_19a() {
781         touch $DIR/$tfile
782         ls -l $DIR
783         rm $DIR/$tfile
784         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
785 }
786 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
787
788 test_19b() {
789         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
790 }
791 run_test 19b "ls -l .../f19 (should return error) =============="
792
793 test_19c() {
794         [ $RUNAS_ID -eq $UID ] &&
795                 skip_env "RUNAS_ID = UID = $UID -- skipping"
796
797         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
798 }
799 run_test 19c "$RUNAS touch .../f19 (should return error) =="
800
801 test_19d() {
802         cat $DIR/f19 && error || true
803 }
804 run_test 19d "cat .../f19 (should return error) =============="
805
806 test_20() {
807         touch $DIR/$tfile
808         rm $DIR/$tfile
809         touch $DIR/$tfile
810         rm $DIR/$tfile
811         touch $DIR/$tfile
812         rm $DIR/$tfile
813         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
814 }
815 run_test 20 "touch .../f ; ls -l ..."
816
817 test_21() {
818         test_mkdir $DIR/$tdir
819         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
820         ln -s dangle $DIR/$tdir/link
821         echo foo >> $DIR/$tdir/link
822         cat $DIR/$tdir/dangle
823         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
824         $CHECKSTAT -f -t file $DIR/$tdir/link ||
825                 error "$tdir/link not linked to a file"
826 }
827 run_test 21 "write to dangling link"
828
829 test_22() {
830         local wdir=$DIR/$tdir
831         test_mkdir $wdir
832         chown $RUNAS_ID:$RUNAS_GID $wdir
833         (cd $wdir || error "cd $wdir failed";
834                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
835                 $RUNAS tar xf -)
836         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
837         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
838         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
839                 error "checkstat -u failed"
840 }
841 run_test 22 "unpack tar archive as non-root user"
842
843 # was test_23
844 test_23a() {
845         test_mkdir $DIR/$tdir
846         local file=$DIR/$tdir/$tfile
847
848         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
849         openfile -f O_CREAT:O_EXCL $file &&
850                 error "$file recreate succeeded" || true
851 }
852 run_test 23a "O_CREAT|O_EXCL in subdir"
853
854 test_23b() { # bug 18988
855         test_mkdir $DIR/$tdir
856         local file=$DIR/$tdir/$tfile
857
858         rm -f $file
859         echo foo > $file || error "write filed"
860         echo bar >> $file || error "append filed"
861         $CHECKSTAT -s 8 $file || error "wrong size"
862         rm $file
863 }
864 run_test 23b "O_APPEND check"
865
866 # LU-9409, size with O_APPEND and tiny writes
867 test_23c() {
868         local file=$DIR/$tfile
869
870         # single dd
871         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
872         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
873         rm -f $file
874
875         # racing tiny writes
876         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
877         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
878         wait
879         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
880         rm -f $file
881
882         #racing tiny & normal writes
883         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
884         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
885         wait
886         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
887         rm -f $file
888
889         #racing tiny & normal writes 2, ugly numbers
890         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
891         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
892         wait
893         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
894         rm -f $file
895 }
896 run_test 23c "O_APPEND size checks for tiny writes"
897
898 # LU-11069 file offset is correct after appending writes
899 test_23d() {
900         local file=$DIR/$tfile
901         local offset
902
903         echo CentaurHauls > $file
904         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
905         if ((offset != 26)); then
906                 error "wrong offset, expected 26, got '$offset'"
907         fi
908 }
909 run_test 23d "file offset is correct after appending writes"
910
911 # rename sanity
912 test_24a() {
913         echo '-- same directory rename'
914         test_mkdir $DIR/$tdir
915         touch $DIR/$tdir/$tfile.1
916         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
917         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
918 }
919 run_test 24a "rename file to non-existent target"
920
921 test_24b() {
922         test_mkdir $DIR/$tdir
923         touch $DIR/$tdir/$tfile.{1,2}
924         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
925         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
926         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
927 }
928 run_test 24b "rename file to existing target"
929
930 test_24c() {
931         test_mkdir $DIR/$tdir
932         test_mkdir $DIR/$tdir/d$testnum.1
933         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
934         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
935         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
936 }
937 run_test 24c "rename directory to non-existent target"
938
939 test_24d() {
940         test_mkdir -c1 $DIR/$tdir
941         test_mkdir -c1 $DIR/$tdir/d$testnum.1
942         test_mkdir -c1 $DIR/$tdir/d$testnum.2
943         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
944         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
945         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
946 }
947 run_test 24d "rename directory to existing target"
948
949 test_24e() {
950         echo '-- cross directory renames --'
951         test_mkdir $DIR/R5a
952         test_mkdir $DIR/R5b
953         touch $DIR/R5a/f
954         mv $DIR/R5a/f $DIR/R5b/g
955         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
956         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
957 }
958 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
959
960 test_24f() {
961         test_mkdir $DIR/R6a
962         test_mkdir $DIR/R6b
963         touch $DIR/R6a/f $DIR/R6b/g
964         mv $DIR/R6a/f $DIR/R6b/g
965         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
966         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
967 }
968 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
969
970 test_24g() {
971         test_mkdir $DIR/R7a
972         test_mkdir $DIR/R7b
973         test_mkdir $DIR/R7a/d
974         mv $DIR/R7a/d $DIR/R7b/e
975         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
976         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
977 }
978 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
979
980 test_24h() {
981         test_mkdir -c1 $DIR/R8a
982         test_mkdir -c1 $DIR/R8b
983         test_mkdir -c1 $DIR/R8a/d
984         test_mkdir -c1 $DIR/R8b/e
985         mrename $DIR/R8a/d $DIR/R8b/e
986         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
987         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
988 }
989 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
990
991 test_24i() {
992         echo "-- rename error cases"
993         test_mkdir $DIR/R9
994         test_mkdir $DIR/R9/a
995         touch $DIR/R9/f
996         mrename $DIR/R9/f $DIR/R9/a
997         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
998         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
999         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1000 }
1001 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1002
1003 test_24j() {
1004         test_mkdir $DIR/R10
1005         mrename $DIR/R10/f $DIR/R10/g
1006         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1007         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1008         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1009 }
1010 run_test 24j "source does not exist ============================"
1011
1012 test_24k() {
1013         test_mkdir $DIR/R11a
1014         test_mkdir $DIR/R11a/d
1015         touch $DIR/R11a/f
1016         mv $DIR/R11a/f $DIR/R11a/d
1017         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1018         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1019 }
1020 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1021
1022 # bug 2429 - rename foo foo foo creates invalid file
1023 test_24l() {
1024         f="$DIR/f24l"
1025         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1026 }
1027 run_test 24l "Renaming a file to itself ========================"
1028
1029 test_24m() {
1030         f="$DIR/f24m"
1031         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1032         # on ext3 this does not remove either the source or target files
1033         # though the "expected" operation would be to remove the source
1034         $CHECKSTAT -t file ${f} || error "${f} missing"
1035         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1036 }
1037 run_test 24m "Renaming a file to a hard link to itself ========="
1038
1039 test_24n() {
1040     f="$DIR/f24n"
1041     # this stats the old file after it was renamed, so it should fail
1042     touch ${f}
1043     $CHECKSTAT ${f} || error "${f} missing"
1044     mv ${f} ${f}.rename
1045     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1046     $CHECKSTAT -a ${f} || error "${f} exists"
1047 }
1048 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1049
1050 test_24o() {
1051         test_mkdir $DIR/$tdir
1052         rename_many -s random -v -n 10 $DIR/$tdir
1053 }
1054 run_test 24o "rename of files during htree split"
1055
1056 test_24p() {
1057         test_mkdir $DIR/R12a
1058         test_mkdir $DIR/R12b
1059         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1060         mrename $DIR/R12a $DIR/R12b
1061         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1062         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1063         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1064         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1065 }
1066 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1067
1068 cleanup_multiop_pause() {
1069         trap 0
1070         kill -USR1 $MULTIPID
1071 }
1072
1073 test_24q() {
1074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1075
1076         test_mkdir $DIR/R13a
1077         test_mkdir $DIR/R13b
1078         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1079         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1080         MULTIPID=$!
1081
1082         trap cleanup_multiop_pause EXIT
1083         mrename $DIR/R13a $DIR/R13b
1084         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1085         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1086         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1087         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1088         cleanup_multiop_pause
1089         wait $MULTIPID || error "multiop close failed"
1090 }
1091 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1092
1093 test_24r() { #bug 3789
1094         test_mkdir $DIR/R14a
1095         test_mkdir $DIR/R14a/b
1096         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1097         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1098         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1099 }
1100 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1101
1102 test_24s() {
1103         test_mkdir $DIR/R15a
1104         test_mkdir $DIR/R15a/b
1105         test_mkdir $DIR/R15a/b/c
1106         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1107         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1108         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1109 }
1110 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1111 test_24t() {
1112         test_mkdir $DIR/R16a
1113         test_mkdir $DIR/R16a/b
1114         test_mkdir $DIR/R16a/b/c
1115         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1116         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1117         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1118 }
1119 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1120
1121 test_24u() { # bug12192
1122         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1123         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1124 }
1125 run_test 24u "create stripe file"
1126
1127 simple_cleanup_common() {
1128         local rc=0
1129         trap 0
1130         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1131
1132         local start=$SECONDS
1133         rm -rf $DIR/$tdir
1134         rc=$?
1135         wait_delete_completed
1136         echo "cleanup time $((SECONDS - start))"
1137         return $rc
1138 }
1139
1140 max_pages_per_rpc() {
1141         local mdtname="$(printf "MDT%04x" ${1:-0})"
1142         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1143 }
1144
1145 test_24v() {
1146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1147
1148         local nrfiles=${COUNT:-100000}
1149         local fname="$DIR/$tdir/$tfile"
1150
1151         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1152         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1153
1154         test_mkdir "$(dirname $fname)"
1155         # assume MDT0000 has the fewest inodes
1156         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1157         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1158         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1159
1160         trap simple_cleanup_common EXIT
1161
1162         createmany -m "$fname" $nrfiles
1163
1164         cancel_lru_locks mdc
1165         lctl set_param mdc.*.stats clear
1166
1167         # was previously test_24D: LU-6101
1168         # readdir() returns correct number of entries after cursor reload
1169         local num_ls=$(ls $DIR/$tdir | wc -l)
1170         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1171         local num_all=$(ls -a $DIR/$tdir | wc -l)
1172         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1173                 [ $num_all -ne $((nrfiles + 2)) ]; then
1174                         error "Expected $nrfiles files, got $num_ls " \
1175                                 "($num_uniq unique $num_all .&..)"
1176         fi
1177         # LU-5 large readdir
1178         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1179         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1180         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1181         # take into account of overhead in lu_dirpage header and end mark in
1182         # each page, plus one in rpc_num calculation.
1183         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1184         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1185         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1186         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1187         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1188         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1189         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1190         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1191                 error "large readdir doesn't take effect: " \
1192                       "$mds_readpage should be about $rpc_max"
1193
1194         simple_cleanup_common
1195 }
1196 run_test 24v "list large directory (test hash collision, b=17560)"
1197
1198 test_24w() { # bug21506
1199         SZ1=234852
1200         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1201         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1202         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1203         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1204         [[ "$SZ1" -eq "$SZ2" ]] ||
1205                 error "Error reading at the end of the file $tfile"
1206 }
1207 run_test 24w "Reading a file larger than 4Gb"
1208
1209 test_24x() {
1210         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1212         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1213                 skip "Need MDS version at least 2.7.56"
1214
1215         local MDTIDX=1
1216         local remote_dir=$DIR/$tdir/remote_dir
1217
1218         test_mkdir $DIR/$tdir
1219         $LFS mkdir -i $MDTIDX $remote_dir ||
1220                 error "create remote directory failed"
1221
1222         test_mkdir $DIR/$tdir/src_dir
1223         touch $DIR/$tdir/src_file
1224         test_mkdir $remote_dir/tgt_dir
1225         touch $remote_dir/tgt_file
1226
1227         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1228                 error "rename dir cross MDT failed!"
1229
1230         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1231                 error "rename file cross MDT failed!"
1232
1233         touch $DIR/$tdir/ln_file
1234         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1235                 error "ln file cross MDT failed"
1236
1237         rm -rf $DIR/$tdir || error "Can not delete directories"
1238 }
1239 run_test 24x "cross MDT rename/link"
1240
1241 test_24y() {
1242         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1244
1245         local remote_dir=$DIR/$tdir/remote_dir
1246         local mdtidx=1
1247
1248         test_mkdir $DIR/$tdir
1249         $LFS mkdir -i $mdtidx $remote_dir ||
1250                 error "create remote directory failed"
1251
1252         test_mkdir $remote_dir/src_dir
1253         touch $remote_dir/src_file
1254         test_mkdir $remote_dir/tgt_dir
1255         touch $remote_dir/tgt_file
1256
1257         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1258                 error "rename subdir in the same remote dir failed!"
1259
1260         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1261                 error "rename files in the same remote dir failed!"
1262
1263         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1264                 error "link files in the same remote dir failed!"
1265
1266         rm -rf $DIR/$tdir || error "Can not delete directories"
1267 }
1268 run_test 24y "rename/link on the same dir should succeed"
1269
1270 test_24z() {
1271         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1272         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1273                 skip "Need MDS version at least 2.12.51"
1274
1275         local index
1276
1277         for index in 0 1; do
1278                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1279                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1280         done
1281
1282         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1283
1284         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1285         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1286
1287         local mdts=$(comma_list $(mdts_nodes))
1288
1289         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1290         stack_trap "do_nodes $mdts $LCTL \
1291                 set_param mdt.*.enable_remote_rename=1" EXIT
1292
1293         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1294
1295         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1296         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1297 }
1298 run_test 24z "cross-MDT rename is done as cp"
1299
1300 test_24A() { # LU-3182
1301         local NFILES=5000
1302
1303         rm -rf $DIR/$tdir
1304         test_mkdir $DIR/$tdir
1305         trap simple_cleanup_common EXIT
1306         createmany -m $DIR/$tdir/$tfile $NFILES
1307         local t=$(ls $DIR/$tdir | wc -l)
1308         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1309         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1310         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1311            [ $v -ne $((NFILES + 2)) ] ; then
1312                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1313         fi
1314
1315         simple_cleanup_common || error "Can not delete directories"
1316 }
1317 run_test 24A "readdir() returns correct number of entries."
1318
1319 test_24B() { # LU-4805
1320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1321
1322         local count
1323
1324         test_mkdir $DIR/$tdir
1325         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1326                 error "create striped dir failed"
1327
1328         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1329         [ $count -eq 2 ] || error "Expected 2, got $count"
1330
1331         touch $DIR/$tdir/striped_dir/a
1332
1333         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1334         [ $count -eq 3 ] || error "Expected 3, got $count"
1335
1336         touch $DIR/$tdir/striped_dir/.f
1337
1338         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1339         [ $count -eq 4 ] || error "Expected 4, got $count"
1340
1341         rm -rf $DIR/$tdir || error "Can not delete directories"
1342 }
1343 run_test 24B "readdir for striped dir return correct number of entries"
1344
1345 test_24C() {
1346         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1347
1348         mkdir $DIR/$tdir
1349         mkdir $DIR/$tdir/d0
1350         mkdir $DIR/$tdir/d1
1351
1352         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1353                 error "create striped dir failed"
1354
1355         cd $DIR/$tdir/d0/striped_dir
1356
1357         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1358         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1359         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1360
1361         [ "$d0_ino" = "$parent_ino" ] ||
1362                 error ".. wrong, expect $d0_ino, get $parent_ino"
1363
1364         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1365                 error "mv striped dir failed"
1366
1367         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1368
1369         [ "$d1_ino" = "$parent_ino" ] ||
1370                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1371 }
1372 run_test 24C "check .. in striped dir"
1373
1374 test_24E() {
1375         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1377
1378         mkdir -p $DIR/$tdir
1379         mkdir $DIR/$tdir/src_dir
1380         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1381                 error "create remote source failed"
1382
1383         touch $DIR/$tdir/src_dir/src_child/a
1384
1385         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1386                 error "create remote target dir failed"
1387
1388         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1389                 error "create remote target child failed"
1390
1391         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1392                 error "rename dir cross MDT failed!"
1393
1394         find $DIR/$tdir
1395
1396         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1397                 error "src_child still exists after rename"
1398
1399         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1400                 error "missing file(a) after rename"
1401
1402         rm -rf $DIR/$tdir || error "Can not delete directories"
1403 }
1404 run_test 24E "cross MDT rename/link"
1405
1406 test_24F () {
1407         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1408
1409         local repeats=1000
1410         [ "$SLOW" = "no" ] && repeats=100
1411
1412         mkdir -p $DIR/$tdir
1413
1414         echo "$repeats repeats"
1415         for ((i = 0; i < repeats; i++)); do
1416                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1417                 touch $DIR/$tdir/test/a || error "touch fails"
1418                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1419                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1420         done
1421
1422         true
1423 }
1424 run_test 24F "hash order vs readdir (LU-11330)"
1425
1426 test_25a() {
1427         echo '== symlink sanity ============================================='
1428
1429         test_mkdir $DIR/d25
1430         ln -s d25 $DIR/s25
1431         touch $DIR/s25/foo ||
1432                 error "File creation in symlinked directory failed"
1433 }
1434 run_test 25a "create file in symlinked directory ==============="
1435
1436 test_25b() {
1437         [ ! -d $DIR/d25 ] && test_25a
1438         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1439 }
1440 run_test 25b "lookup file in symlinked directory ==============="
1441
1442 test_26a() {
1443         test_mkdir $DIR/d26
1444         test_mkdir $DIR/d26/d26-2
1445         ln -s d26/d26-2 $DIR/s26
1446         touch $DIR/s26/foo || error "File creation failed"
1447 }
1448 run_test 26a "multiple component symlink ======================="
1449
1450 test_26b() {
1451         test_mkdir -p $DIR/$tdir/d26-2
1452         ln -s $tdir/d26-2/foo $DIR/s26-2
1453         touch $DIR/s26-2 || error "File creation failed"
1454 }
1455 run_test 26b "multiple component symlink at end of lookup ======"
1456
1457 test_26c() {
1458         test_mkdir $DIR/d26.2
1459         touch $DIR/d26.2/foo
1460         ln -s d26.2 $DIR/s26.2-1
1461         ln -s s26.2-1 $DIR/s26.2-2
1462         ln -s s26.2-2 $DIR/s26.2-3
1463         chmod 0666 $DIR/s26.2-3/foo
1464 }
1465 run_test 26c "chain of symlinks"
1466
1467 # recursive symlinks (bug 439)
1468 test_26d() {
1469         ln -s d26-3/foo $DIR/d26-3
1470 }
1471 run_test 26d "create multiple component recursive symlink"
1472
1473 test_26e() {
1474         [ ! -h $DIR/d26-3 ] && test_26d
1475         rm $DIR/d26-3
1476 }
1477 run_test 26e "unlink multiple component recursive symlink"
1478
1479 # recursive symlinks (bug 7022)
1480 test_26f() {
1481         test_mkdir $DIR/$tdir
1482         test_mkdir $DIR/$tdir/$tfile
1483         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1484         test_mkdir -p lndir/bar1
1485         test_mkdir $DIR/$tdir/$tfile/$tfile
1486         cd $tfile                || error "cd $tfile failed"
1487         ln -s .. dotdot          || error "ln dotdot failed"
1488         ln -s dotdot/lndir lndir || error "ln lndir failed"
1489         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1490         output=`ls $tfile/$tfile/lndir/bar1`
1491         [ "$output" = bar1 ] && error "unexpected output"
1492         rm -r $tfile             || error "rm $tfile failed"
1493         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1494 }
1495 run_test 26f "rm -r of a directory which has recursive symlink"
1496
1497 test_27a() {
1498         test_mkdir $DIR/$tdir
1499         $LFS getstripe $DIR/$tdir
1500         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1501         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1502         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1503 }
1504 run_test 27a "one stripe file"
1505
1506 test_27b() {
1507         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1508
1509         test_mkdir $DIR/$tdir
1510         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1511         $LFS getstripe -c $DIR/$tdir/$tfile
1512         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1513                 error "two-stripe file doesn't have two stripes"
1514
1515         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1516 }
1517 run_test 27b "create and write to two stripe file"
1518
1519 # 27c family tests specific striping, setstripe -o
1520 test_27ca() {
1521         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1522         test_mkdir -p $DIR/$tdir
1523         local osts="1"
1524
1525         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1526         $LFS getstripe -i $DIR/$tdir/$tfile
1527         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1528                 error "stripe not on specified OST"
1529
1530         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1531 }
1532 run_test 27ca "one stripe on specified OST"
1533
1534 test_27cb() {
1535         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1536         test_mkdir -p $DIR/$tdir
1537         local osts="1,0"
1538         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1539         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1540         echo "$getstripe"
1541
1542         # Strip getstripe output to a space separated list of OSTs
1543         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1544                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1545         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1546                 error "stripes not on specified OSTs"
1547
1548         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1549 }
1550 run_test 27cb "two stripes on specified OSTs"
1551
1552 test_27cc() {
1553         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1554         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1555                 skip "server does not support overstriping"
1556
1557         test_mkdir -p $DIR/$tdir
1558         local osts="0,0"
1559         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1560         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1561         echo "$getstripe"
1562
1563         # Strip getstripe output to a space separated list of OSTs
1564         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1565                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1566         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1567                 error "stripes not on specified OSTs"
1568
1569         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1570 }
1571 run_test 27cc "two stripes on the same OST"
1572
1573 test_27cd() {
1574         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1575         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1576                 skip "server does not support overstriping"
1577         test_mkdir -p $DIR/$tdir
1578         local osts="0,1,1,0"
1579         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1580         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1581         echo "$getstripe"
1582
1583         # Strip getstripe output to a space separated list of OSTs
1584         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1585                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1586         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1587                 error "stripes not on specified OSTs"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1590 }
1591 run_test 27cd "four stripes on two OSTs"
1592
1593 test_27ce() {
1594         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1595                 skip_env "too many osts, skipping"
1596         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1597                 skip "server does not support overstriping"
1598         # We do one more stripe than we have OSTs
1599         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1600                 skip_env "ea_inode feature disabled"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts=""
1604         for i in $(seq 0 $OSTCOUNT);
1605         do
1606                 osts=$osts"0"
1607                 if [ $i -ne $OSTCOUNT ]; then
1608                         osts=$osts","
1609                 fi
1610         done
1611         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1612         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1613         echo "$getstripe"
1614
1615         # Strip getstripe output to a space separated list of OSTs
1616         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1617                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1618         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1619                 error "stripes not on specified OSTs"
1620
1621         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1622 }
1623 run_test 27ce "more stripes than OSTs with -o"
1624
1625 test_27d() {
1626         test_mkdir $DIR/$tdir
1627         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1628                 error "setstripe failed"
1629         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1630         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1631 }
1632 run_test 27d "create file with default settings"
1633
1634 test_27e() {
1635         # LU-5839 adds check for existed layout before setting it
1636         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1637                 skip "Need MDS version at least 2.7.56"
1638
1639         test_mkdir $DIR/$tdir
1640         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1641         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1642         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1643 }
1644 run_test 27e "setstripe existing file (should return error)"
1645
1646 test_27f() {
1647         test_mkdir $DIR/$tdir
1648         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1649                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1650         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1651                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1652         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1653         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1654 }
1655 run_test 27f "setstripe with bad stripe size (should return error)"
1656
1657 test_27g() {
1658         test_mkdir $DIR/$tdir
1659         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1660         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1661                 error "$DIR/$tdir/$tfile has object"
1662 }
1663 run_test 27g "$LFS getstripe with no objects"
1664
1665 test_27ga() {
1666         test_mkdir $DIR/$tdir
1667         touch $DIR/$tdir/$tfile || error "touch failed"
1668         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1669         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1670         local rc=$?
1671         (( rc == 2 )) || error "getstripe did not return ENOENT"
1672 }
1673 run_test 27ga "$LFS getstripe with missing file (should return error)"
1674
1675 test_27i() {
1676         test_mkdir $DIR/$tdir
1677         touch $DIR/$tdir/$tfile || error "touch failed"
1678         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1679                 error "missing objects"
1680 }
1681 run_test 27i "$LFS getstripe with some objects"
1682
1683 test_27j() {
1684         test_mkdir $DIR/$tdir
1685         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1686                 error "setstripe failed" || true
1687 }
1688 run_test 27j "setstripe with bad stripe offset (should return error)"
1689
1690 test_27k() { # bug 2844
1691         test_mkdir $DIR/$tdir
1692         local file=$DIR/$tdir/$tfile
1693         local ll_max_blksize=$((4 * 1024 * 1024))
1694         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1695         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1696         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1697         dd if=/dev/zero of=$file bs=4k count=1
1698         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1699         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1700 }
1701 run_test 27k "limit i_blksize for broken user apps"
1702
1703 test_27l() {
1704         mcreate $DIR/$tfile || error "creating file"
1705         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1706                 error "setstripe should have failed" || true
1707 }
1708 run_test 27l "check setstripe permissions (should return error)"
1709
1710 test_27m() {
1711         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1712
1713         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1714                 skip_env "multiple clients -- skipping"
1715
1716         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1717                    head -n1)
1718         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1719                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1720         fi
1721         trap simple_cleanup_common EXIT
1722         test_mkdir $DIR/$tdir
1723         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1724         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1725                 error "dd should fill OST0"
1726         i=2
1727         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1728                 i=$((i + 1))
1729                 [ $i -gt 256 ] && break
1730         done
1731         i=$((i + 1))
1732         touch $DIR/$tdir/$tfile.$i
1733         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1734             awk '{print $1}'| grep -w "0") ] &&
1735                 error "OST0 was full but new created file still use it"
1736         i=$((i + 1))
1737         touch $DIR/$tdir/$tfile.$i
1738         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1739             awk '{print $1}'| grep -w "0") ] &&
1740                 error "OST0 was full but new created file still use it"
1741         simple_cleanup_common
1742 }
1743 run_test 27m "create file while OST0 was full"
1744
1745 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1746 # if the OST isn't full anymore.
1747 reset_enospc() {
1748         local OSTIDX=${1:-""}
1749
1750         local list=$(comma_list $(osts_nodes))
1751         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1752
1753         do_nodes $list lctl set_param fail_loc=0
1754         sync    # initiate all OST_DESTROYs from MDS to OST
1755         sleep_maxage
1756 }
1757
1758 exhaust_precreations() {
1759         local OSTIDX=$1
1760         local FAILLOC=$2
1761         local FAILIDX=${3:-$OSTIDX}
1762         local ofacet=ost$((OSTIDX + 1))
1763
1764         test_mkdir -p -c1 $DIR/$tdir
1765         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1766         local mfacet=mds$((mdtidx + 1))
1767         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1768
1769         local OST=$(ostname_from_index $OSTIDX)
1770
1771         # on the mdt's osc
1772         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1773         local last_id=$(do_facet $mfacet lctl get_param -n \
1774                         osp.$mdtosc_proc1.prealloc_last_id)
1775         local next_id=$(do_facet $mfacet lctl get_param -n \
1776                         osp.$mdtosc_proc1.prealloc_next_id)
1777
1778         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1779         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1780
1781         test_mkdir -p $DIR/$tdir/${OST}
1782         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1783 #define OBD_FAIL_OST_ENOSPC              0x215
1784         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1785         echo "Creating to objid $last_id on ost $OST..."
1786         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1787         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1788         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1789         sleep_maxage
1790 }
1791
1792 exhaust_all_precreations() {
1793         local i
1794         for (( i=0; i < OSTCOUNT; i++ )) ; do
1795                 exhaust_precreations $i $1 -1
1796         done
1797 }
1798
1799 test_27n() {
1800         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1802         remote_mds_nodsh && skip "remote MDS with nodsh"
1803         remote_ost_nodsh && skip "remote OST with nodsh"
1804
1805         reset_enospc
1806         rm -f $DIR/$tdir/$tfile
1807         exhaust_precreations 0 0x80000215
1808         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1809         touch $DIR/$tdir/$tfile || error "touch failed"
1810         $LFS getstripe $DIR/$tdir/$tfile
1811         reset_enospc
1812 }
1813 run_test 27n "create file with some full OSTs"
1814
1815 test_27o() {
1816         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1818         remote_mds_nodsh && skip "remote MDS with nodsh"
1819         remote_ost_nodsh && skip "remote OST with nodsh"
1820
1821         reset_enospc
1822         rm -f $DIR/$tdir/$tfile
1823         exhaust_all_precreations 0x215
1824
1825         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1826
1827         reset_enospc
1828         rm -rf $DIR/$tdir/*
1829 }
1830 run_test 27o "create file with all full OSTs (should error)"
1831
1832 test_27p() {
1833         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1835         remote_mds_nodsh && skip "remote MDS with nodsh"
1836         remote_ost_nodsh && skip "remote OST with nodsh"
1837
1838         reset_enospc
1839         rm -f $DIR/$tdir/$tfile
1840         test_mkdir $DIR/$tdir
1841
1842         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1843         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1844         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1845
1846         exhaust_precreations 0 0x80000215
1847         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1848         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1849         $LFS getstripe $DIR/$tdir/$tfile
1850
1851         reset_enospc
1852 }
1853 run_test 27p "append to a truncated file with some full OSTs"
1854
1855 test_27q() {
1856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1858         remote_mds_nodsh && skip "remote MDS with nodsh"
1859         remote_ost_nodsh && skip "remote OST with nodsh"
1860
1861         reset_enospc
1862         rm -f $DIR/$tdir/$tfile
1863
1864         test_mkdir $DIR/$tdir
1865         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1866         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1867                 error "truncate $DIR/$tdir/$tfile failed"
1868         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1869
1870         exhaust_all_precreations 0x215
1871
1872         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1873         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1874
1875         reset_enospc
1876 }
1877 run_test 27q "append to truncated file with all OSTs full (should error)"
1878
1879 test_27r() {
1880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1882         remote_mds_nodsh && skip "remote MDS with nodsh"
1883         remote_ost_nodsh && skip "remote OST with nodsh"
1884
1885         reset_enospc
1886         rm -f $DIR/$tdir/$tfile
1887         exhaust_precreations 0 0x80000215
1888
1889         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1890
1891         reset_enospc
1892 }
1893 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1894
1895 test_27s() { # bug 10725
1896         test_mkdir $DIR/$tdir
1897         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1898         local stripe_count=0
1899         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1900         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1901                 error "stripe width >= 2^32 succeeded" || true
1902
1903 }
1904 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1905
1906 test_27t() { # bug 10864
1907         WDIR=$(pwd)
1908         WLFS=$(which lfs)
1909         cd $DIR
1910         touch $tfile
1911         $WLFS getstripe $tfile
1912         cd $WDIR
1913 }
1914 run_test 27t "check that utils parse path correctly"
1915
1916 test_27u() { # bug 4900
1917         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1918         remote_mds_nodsh && skip "remote MDS with nodsh"
1919
1920         local index
1921         local list=$(comma_list $(mdts_nodes))
1922
1923 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1924         do_nodes $list $LCTL set_param fail_loc=0x139
1925         test_mkdir -p $DIR/$tdir
1926         trap simple_cleanup_common EXIT
1927         createmany -o $DIR/$tdir/t- 1000
1928         do_nodes $list $LCTL set_param fail_loc=0
1929
1930         TLOG=$TMP/$tfile.getstripe
1931         $LFS getstripe $DIR/$tdir > $TLOG
1932         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1933         unlinkmany $DIR/$tdir/t- 1000
1934         trap 0
1935         [[ $OBJS -gt 0 ]] &&
1936                 error "$OBJS objects created on OST-0. See $TLOG" ||
1937                 rm -f $TLOG
1938 }
1939 run_test 27u "skip object creation on OSC w/o objects"
1940
1941 test_27v() { # bug 4900
1942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1944         remote_mds_nodsh && skip "remote MDS with nodsh"
1945         remote_ost_nodsh && skip "remote OST with nodsh"
1946
1947         exhaust_all_precreations 0x215
1948         reset_enospc
1949
1950         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1951
1952         touch $DIR/$tdir/$tfile
1953         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1954         # all except ost1
1955         for (( i=1; i < OSTCOUNT; i++ )); do
1956                 do_facet ost$i lctl set_param fail_loc=0x705
1957         done
1958         local START=`date +%s`
1959         createmany -o $DIR/$tdir/$tfile 32
1960
1961         local FINISH=`date +%s`
1962         local TIMEOUT=`lctl get_param -n timeout`
1963         local PROCESS=$((FINISH - START))
1964         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1965                error "$FINISH - $START >= $TIMEOUT / 2"
1966         sleep $((TIMEOUT / 2 - PROCESS))
1967         reset_enospc
1968 }
1969 run_test 27v "skip object creation on slow OST"
1970
1971 test_27w() { # bug 10997
1972         test_mkdir $DIR/$tdir
1973         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1974         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1975                 error "stripe size $size != 65536" || true
1976         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1977                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1978 }
1979 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1980
1981 test_27wa() {
1982         [[ $OSTCOUNT -lt 2 ]] &&
1983                 skip_env "skipping multiple stripe count/offset test"
1984
1985         test_mkdir $DIR/$tdir
1986         for i in $(seq 1 $OSTCOUNT); do
1987                 offset=$((i - 1))
1988                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1989                         error "setstripe -c $i -i $offset failed"
1990                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1991                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1992                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1993                 [ $index -ne $offset ] &&
1994                         error "stripe offset $index != $offset" || true
1995         done
1996 }
1997 run_test 27wa "check $LFS setstripe -c -i options"
1998
1999 test_27x() {
2000         remote_ost_nodsh && skip "remote OST with nodsh"
2001         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2003
2004         OFFSET=$(($OSTCOUNT - 1))
2005         OSTIDX=0
2006         local OST=$(ostname_from_index $OSTIDX)
2007
2008         test_mkdir $DIR/$tdir
2009         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2010         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2011         sleep_maxage
2012         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2013         for i in $(seq 0 $OFFSET); do
2014                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2015                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2016                 error "OST0 was degraded but new created file still use it"
2017         done
2018         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2019 }
2020 run_test 27x "create files while OST0 is degraded"
2021
2022 test_27y() {
2023         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2024         remote_mds_nodsh && skip "remote MDS with nodsh"
2025         remote_ost_nodsh && skip "remote OST with nodsh"
2026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2027
2028         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2029         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2030                 osp.$mdtosc.prealloc_last_id)
2031         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2032                 osp.$mdtosc.prealloc_next_id)
2033         local fcount=$((last_id - next_id))
2034         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2035         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2036
2037         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2038                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2039         local OST_DEACTIVE_IDX=-1
2040         local OSC
2041         local OSTIDX
2042         local OST
2043
2044         for OSC in $MDS_OSCS; do
2045                 OST=$(osc_to_ost $OSC)
2046                 OSTIDX=$(index_from_ostuuid $OST)
2047                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2048                         OST_DEACTIVE_IDX=$OSTIDX
2049                 fi
2050                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2051                         echo $OSC "is Deactivated:"
2052                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2053                 fi
2054         done
2055
2056         OSTIDX=$(index_from_ostuuid $OST)
2057         test_mkdir $DIR/$tdir
2058         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2059
2060         for OSC in $MDS_OSCS; do
2061                 OST=$(osc_to_ost $OSC)
2062                 OSTIDX=$(index_from_ostuuid $OST)
2063                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2064                         echo $OST "is degraded:"
2065                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2066                                                 obdfilter.$OST.degraded=1
2067                 fi
2068         done
2069
2070         sleep_maxage
2071         createmany -o $DIR/$tdir/$tfile $fcount
2072
2073         for OSC in $MDS_OSCS; do
2074                 OST=$(osc_to_ost $OSC)
2075                 OSTIDX=$(index_from_ostuuid $OST)
2076                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2077                         echo $OST "is recovered from degraded:"
2078                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2079                                                 obdfilter.$OST.degraded=0
2080                 else
2081                         do_facet $SINGLEMDS lctl --device %$OSC activate
2082                 fi
2083         done
2084
2085         # all osp devices get activated, hence -1 stripe count restored
2086         local stripe_count=0
2087
2088         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2089         # devices get activated.
2090         sleep_maxage
2091         $LFS setstripe -c -1 $DIR/$tfile
2092         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2093         rm -f $DIR/$tfile
2094         [ $stripe_count -ne $OSTCOUNT ] &&
2095                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2096         return 0
2097 }
2098 run_test 27y "create files while OST0 is degraded and the rest inactive"
2099
2100 check_seq_oid()
2101 {
2102         log "check file $1"
2103
2104         lmm_count=$($LFS getstripe -c $1)
2105         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2106         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2107
2108         local old_ifs="$IFS"
2109         IFS=$'[:]'
2110         fid=($($LFS path2fid $1))
2111         IFS="$old_ifs"
2112
2113         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2114         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2115
2116         # compare lmm_seq and lu_fid->f_seq
2117         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2118         # compare lmm_object_id and lu_fid->oid
2119         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2120
2121         # check the trusted.fid attribute of the OST objects of the file
2122         local have_obdidx=false
2123         local stripe_nr=0
2124         $LFS getstripe $1 | while read obdidx oid hex seq; do
2125                 # skip lines up to and including "obdidx"
2126                 [ -z "$obdidx" ] && break
2127                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2128                 $have_obdidx || continue
2129
2130                 local ost=$((obdidx + 1))
2131                 local dev=$(ostdevname $ost)
2132                 local oid_hex
2133
2134                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2135
2136                 seq=$(echo $seq | sed -e "s/^0x//g")
2137                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2138                         oid_hex=$(echo $oid)
2139                 else
2140                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2141                 fi
2142                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2143
2144                 local ff=""
2145                 #
2146                 # Don't unmount/remount the OSTs if we don't need to do that.
2147                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2148                 # update too, until that use mount/ll_decode_filter_fid/mount.
2149                 # Re-enable when debugfs will understand new filter_fid.
2150                 #
2151                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2152                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2153                                 $dev 2>/dev/null" | grep "parent=")
2154                 fi
2155                 if [ -z "$ff" ]; then
2156                         stop ost$ost
2157                         mount_fstype ost$ost
2158                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2159                                 $(facet_mntpt ost$ost)/$obj_file)
2160                         unmount_fstype ost$ost
2161                         start ost$ost $dev $OST_MOUNT_OPTS
2162                         clients_up
2163                 fi
2164
2165                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2166
2167                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2168
2169                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2170                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2171                 #
2172                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2173                 #       stripe_size=1048576 component_id=1 component_start=0 \
2174                 #       component_end=33554432
2175                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2176                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2177                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2178                 local ff_pstripe
2179                 if grep -q 'stripe=' <<<$ff; then
2180                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2181                 else
2182                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2183                         # into f_ver in this case.  See comment on ff_parent.
2184                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2185                 fi
2186
2187                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2188                 [ $ff_pseq = $lmm_seq ] ||
2189                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2190                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2191                 [ $ff_poid = $lmm_oid ] ||
2192                         error "FF parent OID $ff_poid != $lmm_oid"
2193                 (($ff_pstripe == $stripe_nr)) ||
2194                         error "FF stripe $ff_pstripe != $stripe_nr"
2195
2196                 stripe_nr=$((stripe_nr + 1))
2197                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2198                         continue
2199                 if grep -q 'stripe_count=' <<<$ff; then
2200                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2201                                             -e 's/ .*//' <<<$ff)
2202                         [ $lmm_count = $ff_scnt ] ||
2203                                 error "FF stripe count $lmm_count != $ff_scnt"
2204                 fi
2205         done
2206 }
2207
2208 test_27z() {
2209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2210         remote_ost_nodsh && skip "remote OST with nodsh"
2211
2212         test_mkdir $DIR/$tdir
2213         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2214                 { error "setstripe -c -1 failed"; return 1; }
2215         # We need to send a write to every object to get parent FID info set.
2216         # This _should_ also work for setattr, but does not currently.
2217         # touch $DIR/$tdir/$tfile-1 ||
2218         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2219                 { error "dd $tfile-1 failed"; return 2; }
2220         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2221                 { error "setstripe -c -1 failed"; return 3; }
2222         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2223                 { error "dd $tfile-2 failed"; return 4; }
2224
2225         # make sure write RPCs have been sent to OSTs
2226         sync; sleep 5; sync
2227
2228         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2229         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2230 }
2231 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2232
2233 test_27A() { # b=19102
2234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2235
2236         save_layout_restore_at_exit $MOUNT
2237         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2238         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2239                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2240         local default_size=$($LFS getstripe -S $MOUNT)
2241         local default_offset=$($LFS getstripe -i $MOUNT)
2242         local dsize=$(do_facet $SINGLEMDS \
2243                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2244         [ $default_size -eq $dsize ] ||
2245                 error "stripe size $default_size != $dsize"
2246         [ $default_offset -eq -1 ] ||
2247                 error "stripe offset $default_offset != -1"
2248 }
2249 run_test 27A "check filesystem-wide default LOV EA values"
2250
2251 test_27B() { # LU-2523
2252         test_mkdir $DIR/$tdir
2253         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2254         touch $DIR/$tdir/f0
2255         # open f1 with O_LOV_DELAY_CREATE
2256         # rename f0 onto f1
2257         # call setstripe ioctl on open file descriptor for f1
2258         # close
2259         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2260                 $DIR/$tdir/f0
2261
2262         rm -f $DIR/$tdir/f1
2263         # open f1 with O_LOV_DELAY_CREATE
2264         # unlink f1
2265         # call setstripe ioctl on open file descriptor for f1
2266         # close
2267         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2268
2269         # Allow multiop to fail in imitation of NFS's busted semantics.
2270         true
2271 }
2272 run_test 27B "call setstripe on open unlinked file/rename victim"
2273
2274 # 27C family tests full striping and overstriping
2275 test_27Ca() { #LU-2871
2276         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2277
2278         declare -a ost_idx
2279         local index
2280         local found
2281         local i
2282         local j
2283
2284         test_mkdir $DIR/$tdir
2285         cd $DIR/$tdir
2286         for i in $(seq 0 $((OSTCOUNT - 1))); do
2287                 # set stripe across all OSTs starting from OST$i
2288                 $LFS setstripe -i $i -c -1 $tfile$i
2289                 # get striping information
2290                 ost_idx=($($LFS getstripe $tfile$i |
2291                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2292                 echo ${ost_idx[@]}
2293
2294                 # check the layout
2295                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2296                         error "${#ost_idx[@]} != $OSTCOUNT"
2297
2298                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2299                         found=0
2300                         for j in $(echo ${ost_idx[@]}); do
2301                                 if [ $index -eq $j ]; then
2302                                         found=1
2303                                         break
2304                                 fi
2305                         done
2306                         [ $found = 1 ] ||
2307                                 error "Can not find $index in ${ost_idx[@]}"
2308                 done
2309         done
2310 }
2311 run_test 27Ca "check full striping across all OSTs"
2312
2313 test_27Cb() {
2314         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2315                 skip "server does not support overstriping"
2316         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2317                 skip_env "too many osts, skipping"
2318
2319         test_mkdir -p $DIR/$tdir
2320         local setcount=$(($OSTCOUNT * 2))
2321         [ $setcount -ge 160 ] || large_xattr_enabled ||
2322                 skip_env "ea_inode feature disabled"
2323
2324         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2325                 error "setstripe failed"
2326
2327         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2328         [ $count -eq $setcount ] ||
2329                 error "stripe count $count, should be $setcount"
2330
2331         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2332                 error "overstriped should be set in pattern"
2333
2334         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2335                 error "dd failed"
2336 }
2337 run_test 27Cb "more stripes than OSTs with -C"
2338
2339 test_27Cc() {
2340         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2341                 skip "server does not support overstriping"
2342         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2343
2344         test_mkdir -p $DIR/$tdir
2345         local setcount=$(($OSTCOUNT - 1))
2346
2347         [ $setcount -ge 160 ] || large_xattr_enabled ||
2348                 skip_env "ea_inode feature disabled"
2349
2350         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2351                 error "setstripe failed"
2352
2353         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2354         [ $count -eq $setcount ] ||
2355                 error "stripe count $count, should be $setcount"
2356
2357         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2358                 error "overstriped should not be set in pattern"
2359
2360         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2361                 error "dd failed"
2362 }
2363 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2364
2365 test_27Cd() {
2366         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2367                 skip "server does not support overstriping"
2368         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2369         large_xattr_enabled || skip_env "ea_inode feature disabled"
2370
2371         test_mkdir -p $DIR/$tdir
2372         local setcount=$LOV_MAX_STRIPE_COUNT
2373
2374         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2375                 error "setstripe failed"
2376
2377         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2378         [ $count -eq $setcount ] ||
2379                 error "stripe count $count, should be $setcount"
2380
2381         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2382                 error "overstriped should be set in pattern"
2383
2384         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2385                 error "dd failed"
2386
2387         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2388 }
2389 run_test 27Cd "test maximum stripe count"
2390
2391 test_27Ce() {
2392         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2393                 skip "server does not support overstriping"
2394         test_mkdir -p $DIR/$tdir
2395
2396         pool_add $TESTNAME || error "Pool creation failed"
2397         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2398
2399         local setcount=8
2400
2401         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2402                 error "setstripe failed"
2403
2404         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2405         [ $count -eq $setcount ] ||
2406                 error "stripe count $count, should be $setcount"
2407
2408         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2409                 error "overstriped should be set in pattern"
2410
2411         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2412                 error "dd failed"
2413
2414         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2415 }
2416 run_test 27Ce "test pool with overstriping"
2417
2418 test_27Cf() {
2419         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2420                 skip "server does not support overstriping"
2421         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2422                 skip_env "too many osts, skipping"
2423
2424         test_mkdir -p $DIR/$tdir
2425
2426         local setcount=$(($OSTCOUNT * 2))
2427         [ $setcount -ge 160 ] || large_xattr_enabled ||
2428                 skip_env "ea_inode feature disabled"
2429
2430         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2431                 error "setstripe failed"
2432
2433         echo 1 > $DIR/$tdir/$tfile
2434
2435         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2436         [ $count -eq $setcount ] ||
2437                 error "stripe count $count, should be $setcount"
2438
2439         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2440                 error "overstriped should be set in pattern"
2441
2442         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2443                 error "dd failed"
2444
2445         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2446 }
2447 run_test 27Cf "test default inheritance with overstriping"
2448
2449 test_27D() {
2450         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2451         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2452         remote_mds_nodsh && skip "remote MDS with nodsh"
2453
2454         local POOL=${POOL:-testpool}
2455         local first_ost=0
2456         local last_ost=$(($OSTCOUNT - 1))
2457         local ost_step=1
2458         local ost_list=$(seq $first_ost $ost_step $last_ost)
2459         local ost_range="$first_ost $last_ost $ost_step"
2460
2461         test_mkdir $DIR/$tdir
2462         pool_add $POOL || error "pool_add failed"
2463         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2464
2465         local skip27D
2466         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2467                 skip27D+="-s 29"
2468         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2469                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2470                         skip27D+=" -s 30,31"
2471         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code $SEL_VER) ] &&
2472                 skip27D+="-s 32"
2473         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2474           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2475                 skip27D+=" -s 32,33"
2476         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2477                 error "llapi_layout_test failed"
2478
2479         destroy_test_pools || error "destroy test pools failed"
2480 }
2481 run_test 27D "validate llapi_layout API"
2482
2483 # Verify that default_easize is increased from its initial value after
2484 # accessing a widely striped file.
2485 test_27E() {
2486         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2487         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2488                 skip "client does not have LU-3338 fix"
2489
2490         # 72 bytes is the minimum space required to store striping
2491         # information for a file striped across one OST:
2492         # (sizeof(struct lov_user_md_v3) +
2493         #  sizeof(struct lov_user_ost_data_v1))
2494         local min_easize=72
2495         $LCTL set_param -n llite.*.default_easize $min_easize ||
2496                 error "lctl set_param failed"
2497         local easize=$($LCTL get_param -n llite.*.default_easize)
2498
2499         [ $easize -eq $min_easize ] ||
2500                 error "failed to set default_easize"
2501
2502         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2503                 error "setstripe failed"
2504         # In order to ensure stat() call actually talks to MDS we need to
2505         # do something drastic to this file to shake off all lock, e.g.
2506         # rename it (kills lookup lock forcing cache cleaning)
2507         mv $DIR/$tfile $DIR/${tfile}-1
2508         ls -l $DIR/${tfile}-1
2509         rm $DIR/${tfile}-1
2510
2511         easize=$($LCTL get_param -n llite.*.default_easize)
2512
2513         [ $easize -gt $min_easize ] ||
2514                 error "default_easize not updated"
2515 }
2516 run_test 27E "check that default extended attribute size properly increases"
2517
2518 test_27F() { # LU-5346/LU-7975
2519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2520         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2521         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2522                 skip "Need MDS version at least 2.8.51"
2523         remote_ost_nodsh && skip "remote OST with nodsh"
2524
2525         test_mkdir $DIR/$tdir
2526         rm -f $DIR/$tdir/f0
2527         $LFS setstripe -c 2 $DIR/$tdir
2528
2529         # stop all OSTs to reproduce situation for LU-7975 ticket
2530         for num in $(seq $OSTCOUNT); do
2531                 stop ost$num
2532         done
2533
2534         # open/create f0 with O_LOV_DELAY_CREATE
2535         # truncate f0 to a non-0 size
2536         # close
2537         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2538
2539         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2540         # open/write it again to force delayed layout creation
2541         cat /etc/hosts > $DIR/$tdir/f0 &
2542         catpid=$!
2543
2544         # restart OSTs
2545         for num in $(seq $OSTCOUNT); do
2546                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2547                         error "ost$num failed to start"
2548         done
2549
2550         wait $catpid || error "cat failed"
2551
2552         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2553         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2554                 error "wrong stripecount"
2555
2556 }
2557 run_test 27F "Client resend delayed layout creation with non-zero size"
2558
2559 test_27G() { #LU-10629
2560         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2561                 skip "Need MDS version at least 2.11.51"
2562         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2563         remote_mds_nodsh && skip "remote MDS with nodsh"
2564         local POOL=${POOL:-testpool}
2565         local ostrange="0 0 1"
2566
2567         test_mkdir $DIR/$tdir
2568         pool_add $POOL || error "pool_add failed"
2569         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2570         $LFS setstripe -p $POOL $DIR/$tdir
2571
2572         local pool=$($LFS getstripe -p $DIR/$tdir)
2573
2574         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2575
2576         $LFS setstripe -d $DIR/$tdir
2577
2578         pool=$($LFS getstripe -p $DIR/$tdir)
2579
2580         rmdir $DIR/$tdir
2581
2582         [ -z "$pool" ] || error "'$pool' is not empty"
2583 }
2584 run_test 27G "Clear OST pool from stripe"
2585
2586 test_27H() {
2587         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2588                 skip "Need MDS version newer than 2.11.54"
2589         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2590         test_mkdir $DIR/$tdir
2591         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2592         touch $DIR/$tdir/$tfile
2593         $LFS getstripe -c $DIR/$tdir/$tfile
2594         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2595                 error "two-stripe file doesn't have two stripes"
2596
2597         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2598         $LFS getstripe -y $DIR/$tdir/$tfile
2599         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2600              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2601                 error "expected l_ost_idx: [02]$ not matched"
2602
2603         # make sure ost list has been cleared
2604         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2605         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2606                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2607         touch $DIR/$tdir/f3
2608         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2609 }
2610 run_test 27H "Set specific OSTs stripe"
2611
2612 test_27I() {
2613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2614         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2615         local pool=$TESTNAME
2616         local ostrange="1 1 1"
2617
2618         save_layout_restore_at_exit $MOUNT
2619         $LFS setstripe -c 2 -i 0 $MOUNT
2620         pool_add $pool || error "pool_add failed"
2621         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2622         test_mkdir $DIR/$tdir
2623         $LFS setstripe -p $pool $DIR/$tdir
2624         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2625         $LFS getstripe $DIR/$tdir/$tfile
2626 }
2627 run_test 27I "check that root dir striping does not break parent dir one"
2628
2629 test_27J() {
2630         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
2631                 skip "Need MDS version newer than 2.12.51"
2632
2633         test_mkdir $DIR/$tdir
2634         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2635         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2636
2637         # create foreign file (raw way)
2638         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2639                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2640
2641         # verify foreign file (raw way)
2642         parse_foreign_file -f $DIR/$tdir/$tfile |
2643                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2644                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2645         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2646                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2647         parse_foreign_file -f $DIR/$tdir/$tfile |
2648                 grep "lov_foreign_size: 73" ||
2649                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2650         parse_foreign_file -f $DIR/$tdir/$tfile |
2651                 grep "lov_foreign_type: 1" ||
2652                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2653         parse_foreign_file -f $DIR/$tdir/$tfile |
2654                 grep "lov_foreign_flags: 0x0000DA08" ||
2655                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2656         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2657                 grep "lov_foreign_value: 0x" |
2658                 sed -e 's/lov_foreign_value: 0x//')
2659         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2660         [[ $lov = ${lov2// /} ]] ||
2661                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2662
2663         # create foreign file (lfs + API)
2664         $LFS setstripe --foreign=daos --flags 0xda08 \
2665                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2666                 error "$DIR/$tdir/${tfile}2: create failed"
2667
2668         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2669                 grep "lfm_magic:.*0x0BD70BD0" ||
2670                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2671         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2672         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2673                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2674         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2675                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2676         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2677                 grep "lfm_flags:.*0x0000DA08" ||
2678                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2679         $LFS getstripe $DIR/$tdir/${tfile}2 |
2680                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2681                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2682
2683         # modify striping should fail
2684         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2685                 error "$DIR/$tdir/$tfile: setstripe should fail"
2686         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2687                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2688
2689         # R/W should fail
2690         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2691         cat $DIR/$tdir/${tfile}2 &&
2692                 error "$DIR/$tdir/${tfile}2: read should fail"
2693         cat /etc/passwd > $DIR/$tdir/$tfile &&
2694                 error "$DIR/$tdir/$tfile: write should fail"
2695         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2696                 error "$DIR/$tdir/${tfile}2: write should fail"
2697
2698         # chmod should work
2699         chmod 222 $DIR/$tdir/$tfile ||
2700                 error "$DIR/$tdir/$tfile: chmod failed"
2701         chmod 222 $DIR/$tdir/${tfile}2 ||
2702                 error "$DIR/$tdir/${tfile}2: chmod failed"
2703
2704         # chown should work
2705         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2706                 error "$DIR/$tdir/$tfile: chown failed"
2707         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2708                 error "$DIR/$tdir/${tfile}2: chown failed"
2709
2710         # rename should work
2711         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2712                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2713         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2714                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2715
2716         #remove foreign file
2717         rm $DIR/$tdir/${tfile}.new ||
2718                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2719         rm $DIR/$tdir/${tfile}2.new ||
2720                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2721 }
2722 run_test 27J "basic ops on file with foreign LOV"
2723
2724 test_27K() {
2725         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
2726                 skip "Need MDS version newer than 2.12.49"
2727
2728         test_mkdir $DIR/$tdir
2729         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2730         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2731
2732         # create foreign dir (raw way)
2733         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2734                 error "create_foreign_dir FAILED"
2735
2736         # verify foreign dir (raw way)
2737         parse_foreign_dir -d $DIR/$tdir/$tdir |
2738                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2739                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2740         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2741                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2742         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2743                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2744         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2745                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2746         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2747                 grep "lmv_foreign_value: 0x" |
2748                 sed 's/lmv_foreign_value: 0x//')
2749         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2750                 sed 's/ //g')
2751         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2752
2753         # create foreign dir (lfs + API)
2754         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2755                 $DIR/$tdir/${tdir}2 ||
2756                 error "$DIR/$tdir/${tdir}2: create failed"
2757
2758         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2759                 grep "lfm_magic:.*0x0CD50CD0" ||
2760                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2761         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2762         # - sizeof(lfm_type) - sizeof(lfm_flags)
2763         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2764                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2765         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2766                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2767         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2768                 grep "lfm_flags:.*0x0000DA05" ||
2769                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2770         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2771                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2772                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2773
2774         # file create in dir should fail
2775         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2776         touch $DIR/$tdir/${tdir}2/$tfile &&
2777                 "$DIR/${tdir}2: file create should fail"
2778
2779         # chmod should work
2780         chmod 777 $DIR/$tdir/$tdir ||
2781                 error "$DIR/$tdir: chmod failed"
2782         chmod 777 $DIR/$tdir/${tdir}2 ||
2783                 error "$DIR/${tdir}2: chmod failed"
2784
2785         # chown should work
2786         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2787                 error "$DIR/$tdir: chown failed"
2788         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2789                 error "$DIR/${tdir}2: chown failed"
2790
2791         # rename should work
2792         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2793                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2794         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2795                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2796
2797         #remove foreign dir
2798         rmdir $DIR/$tdir/${tdir}.new ||
2799                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2800         rmdir $DIR/$tdir/${tdir}2.new ||
2801                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2802 }
2803 run_test 27K "basic ops on dir with foreign LMV"
2804
2805 test_27L() {
2806         remote_mds_nodsh && skip "remote MDS with nodsh"
2807
2808         local POOL=${POOL:-$TESTNAME}
2809
2810         pool_add $POOL || error "pool_add failed"
2811
2812         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2813                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2814                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2815 }
2816 run_test 27L "lfs pool_list gives correct pool name"
2817
2818 test_27M() {
2819         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2820                 skip "Need MDS version >= than 2.12.57"
2821         remote_mds_nodsh && skip "remote MDS with nodsh"
2822         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2823
2824         test_mkdir $DIR/$tdir
2825
2826         # Set default striping on directory
2827         $LFS setstripe -C 4 $DIR/$tdir
2828
2829         echo 1 > $DIR/$tdir/${tfile}.1
2830         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2831         local setcount=4
2832         [ $count -eq $setcount ] ||
2833                 error "(1) stripe count $count, should be $setcount"
2834
2835         # Capture existing append_stripe_count setting for restore
2836         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2837         local mdts=$(comma_list $(mdts_nodes))
2838         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2839
2840         local appendcount=$orig_count
2841         echo 1 >> $DIR/$tdir/${tfile}.2_append
2842         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2843         [ $count -eq $appendcount ] ||
2844                 error "(2)stripe count $count, should be $appendcount for append"
2845
2846         # Disable O_APPEND striping, verify it works
2847         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2848
2849         # Should now get the default striping, which is 4
2850         setcount=4
2851         echo 1 >> $DIR/$tdir/${tfile}.3_append
2852         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2853         [ $count -eq $setcount ] ||
2854                 error "(3) stripe count $count, should be $setcount"
2855
2856         # Try changing the stripe count for append files
2857         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2858
2859         # Append striping is now 2 (directory default is still 4)
2860         appendcount=2
2861         echo 1 >> $DIR/$tdir/${tfile}.4_append
2862         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2863         [ $count -eq $appendcount ] ||
2864                 error "(4) stripe count $count, should be $appendcount for append"
2865
2866         # Test append stripe count of -1
2867         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2868         appendcount=$OSTCOUNT
2869         echo 1 >> $DIR/$tdir/${tfile}.5
2870         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2871         [ $count -eq $appendcount ] ||
2872                 error "(5) stripe count $count, should be $appendcount for append"
2873
2874         # Set append striping back to default of 1
2875         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2876
2877         # Try a new default striping, PFL + DOM
2878         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2879
2880         # Create normal DOM file, DOM returns stripe count == 0
2881         setcount=0
2882         touch $DIR/$tdir/${tfile}.6
2883         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2884         [ $count -eq $setcount ] ||
2885                 error "(6) stripe count $count, should be $setcount"
2886
2887         # Show
2888         appendcount=1
2889         echo 1 >> $DIR/$tdir/${tfile}.7_append
2890         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2891         [ $count -eq $appendcount ] ||
2892                 error "(7) stripe count $count, should be $appendcount for append"
2893
2894         # Clean up DOM layout
2895         $LFS setstripe -d $DIR/$tdir
2896
2897         # Now test that append striping works when layout is from root
2898         $LFS setstripe -c 2 $MOUNT
2899         # Make a special directory for this
2900         mkdir $DIR/${tdir}/${tdir}.2
2901         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2902
2903         # Verify for normal file
2904         setcount=2
2905         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2906         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2907         [ $count -eq $setcount ] ||
2908                 error "(8) stripe count $count, should be $setcount"
2909
2910         appendcount=1
2911         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2912         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2913         [ $count -eq $appendcount ] ||
2914                 error "(9) stripe count $count, should be $appendcount for append"
2915
2916         # Now test O_APPEND striping with pools
2917         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2918         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2919
2920         # Create the pool
2921         pool_add $TESTNAME || error "pool creation failed"
2922         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2923
2924         echo 1 >> $DIR/$tdir/${tfile}.10_append
2925
2926         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2927         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2928
2929         # Check that count is still correct
2930         appendcount=1
2931         echo 1 >> $DIR/$tdir/${tfile}.11_append
2932         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2933         [ $count -eq $appendcount ] ||
2934                 error "(11) stripe count $count, should be $appendcount for append"
2935
2936         # Disable O_APPEND stripe count, verify pool works separately
2937         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2938
2939         echo 1 >> $DIR/$tdir/${tfile}.12_append
2940
2941         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
2942         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
2943
2944         # Remove pool setting, verify it's not applied
2945         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
2946
2947         echo 1 >> $DIR/$tdir/${tfile}.13_append
2948
2949         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
2950         [ "$pool" = "" ] || error "(13) pool found: $pool"
2951 }
2952 run_test 27M "test O_APPEND striping"
2953
2954 test_27N() {
2955         combined_mgs_mds && skip "needs separate MGS/MDT"
2956
2957         pool_add $TESTNAME || error "pool_add failed"
2958         do_facet mgs "$LCTL pool_list $FSNAME" |
2959                 grep -Fx "${FSNAME}.${TESTNAME}" ||
2960                 error "lctl pool_list on MGS failed"
2961 }
2962 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
2963
2964 # createtest also checks that device nodes are created and
2965 # then visible correctly (#2091)
2966 test_28() { # bug 2091
2967         test_mkdir $DIR/d28
2968         $CREATETEST $DIR/d28/ct || error "createtest failed"
2969 }
2970 run_test 28 "create/mknod/mkdir with bad file types ============"
2971
2972 test_29() {
2973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2974
2975         sync; sleep 1; sync # flush out any dirty pages from previous tests
2976         cancel_lru_locks
2977         test_mkdir $DIR/d29
2978         touch $DIR/d29/foo
2979         log 'first d29'
2980         ls -l $DIR/d29
2981
2982         declare -i LOCKCOUNTORIG=0
2983         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2984                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2985         done
2986         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2987
2988         declare -i LOCKUNUSEDCOUNTORIG=0
2989         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2990                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2991         done
2992
2993         log 'second d29'
2994         ls -l $DIR/d29
2995         log 'done'
2996
2997         declare -i LOCKCOUNTCURRENT=0
2998         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2999                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3000         done
3001
3002         declare -i LOCKUNUSEDCOUNTCURRENT=0
3003         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3004                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3005         done
3006
3007         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3008                 $LCTL set_param -n ldlm.dump_namespaces ""
3009                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3010                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3011                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3012                 return 2
3013         fi
3014         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3015                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3016                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3017                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3018                 return 3
3019         fi
3020 }
3021 run_test 29 "IT_GETATTR regression  ============================"
3022
3023 test_30a() { # was test_30
3024         cp $(which ls) $DIR || cp /bin/ls $DIR
3025         $DIR/ls / || error "Can't execute binary from lustre"
3026         rm $DIR/ls
3027 }
3028 run_test 30a "execute binary from Lustre (execve) =============="
3029
3030 test_30b() {
3031         cp `which ls` $DIR || cp /bin/ls $DIR
3032         chmod go+rx $DIR/ls
3033         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3034         rm $DIR/ls
3035 }
3036 run_test 30b "execute binary from Lustre as non-root ==========="
3037
3038 test_30c() { # b=22376
3039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3040
3041         cp `which ls` $DIR || cp /bin/ls $DIR
3042         chmod a-rw $DIR/ls
3043         cancel_lru_locks mdc
3044         cancel_lru_locks osc
3045         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3046         rm -f $DIR/ls
3047 }
3048 run_test 30c "execute binary from Lustre without read perms ===="
3049
3050 test_31a() {
3051         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3052         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3053 }
3054 run_test 31a "open-unlink file =================================="
3055
3056 test_31b() {
3057         touch $DIR/f31 || error "touch $DIR/f31 failed"
3058         ln $DIR/f31 $DIR/f31b || error "ln failed"
3059         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3060         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3061 }
3062 run_test 31b "unlink file with multiple links while open ======="
3063
3064 test_31c() {
3065         touch $DIR/f31 || error "touch $DIR/f31 failed"
3066         ln $DIR/f31 $DIR/f31c || error "ln failed"
3067         multiop_bg_pause $DIR/f31 O_uc ||
3068                 error "multiop_bg_pause for $DIR/f31 failed"
3069         MULTIPID=$!
3070         $MULTIOP $DIR/f31c Ouc
3071         kill -USR1 $MULTIPID
3072         wait $MULTIPID
3073 }
3074 run_test 31c "open-unlink file with multiple links ============="
3075
3076 test_31d() {
3077         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3078         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3079 }
3080 run_test 31d "remove of open directory ========================="
3081
3082 test_31e() { # bug 2904
3083         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3084 }
3085 run_test 31e "remove of open non-empty directory ==============="
3086
3087 test_31f() { # bug 4554
3088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3089
3090         set -vx
3091         test_mkdir $DIR/d31f
3092         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3093         cp /etc/hosts $DIR/d31f
3094         ls -l $DIR/d31f
3095         $LFS getstripe $DIR/d31f/hosts
3096         multiop_bg_pause $DIR/d31f D_c || return 1
3097         MULTIPID=$!
3098
3099         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3100         test_mkdir $DIR/d31f
3101         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3102         cp /etc/hosts $DIR/d31f
3103         ls -l $DIR/d31f
3104         $LFS getstripe $DIR/d31f/hosts
3105         multiop_bg_pause $DIR/d31f D_c || return 1
3106         MULTIPID2=$!
3107
3108         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3109         wait $MULTIPID || error "first opendir $MULTIPID failed"
3110
3111         sleep 6
3112
3113         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3114         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3115         set +vx
3116 }
3117 run_test 31f "remove of open directory with open-unlink file ==="
3118
3119 test_31g() {
3120         echo "-- cross directory link --"
3121         test_mkdir -c1 $DIR/${tdir}ga
3122         test_mkdir -c1 $DIR/${tdir}gb
3123         touch $DIR/${tdir}ga/f
3124         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3125         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3126         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3127         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3128         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3129 }
3130 run_test 31g "cross directory link==============="
3131
3132 test_31h() {
3133         echo "-- cross directory link --"
3134         test_mkdir -c1 $DIR/${tdir}
3135         test_mkdir -c1 $DIR/${tdir}/dir
3136         touch $DIR/${tdir}/f
3137         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3138         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3139         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3140         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3141         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3142 }
3143 run_test 31h "cross directory link under child==============="
3144
3145 test_31i() {
3146         echo "-- cross directory link --"
3147         test_mkdir -c1 $DIR/$tdir
3148         test_mkdir -c1 $DIR/$tdir/dir
3149         touch $DIR/$tdir/dir/f
3150         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3151         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3152         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3153         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3154         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3155 }
3156 run_test 31i "cross directory link under parent==============="
3157
3158 test_31j() {
3159         test_mkdir -c1 -p $DIR/$tdir
3160         test_mkdir -c1 -p $DIR/$tdir/dir1
3161         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3162         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3163         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3164         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3165         return 0
3166 }
3167 run_test 31j "link for directory==============="
3168
3169 test_31k() {
3170         test_mkdir -c1 -p $DIR/$tdir
3171         touch $DIR/$tdir/s
3172         touch $DIR/$tdir/exist
3173         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3174         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3175         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3176         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3177         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3178         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3179         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3180         return 0
3181 }
3182 run_test 31k "link to file: the same, non-existing, dir==============="
3183
3184 test_31m() {
3185         mkdir $DIR/d31m
3186         touch $DIR/d31m/s
3187         mkdir $DIR/d31m2
3188         touch $DIR/d31m2/exist
3189         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3190         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3191         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3192         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3193         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3194         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3195         return 0
3196 }
3197 run_test 31m "link to file: the same, non-existing, dir==============="
3198
3199 test_31n() {
3200         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3201         nlink=$(stat --format=%h $DIR/$tfile)
3202         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3203         local fd=$(free_fd)
3204         local cmd="exec $fd<$DIR/$tfile"
3205         eval $cmd
3206         cmd="exec $fd<&-"
3207         trap "eval $cmd" EXIT
3208         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3209         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3210         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3211         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3212         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3213         eval $cmd
3214 }
3215 run_test 31n "check link count of unlinked file"
3216
3217 link_one() {
3218         local tempfile=$(mktemp $1_XXXXXX)
3219         mlink $tempfile $1 2> /dev/null &&
3220                 echo "$BASHPID: link $tempfile to $1 succeeded"
3221         munlink $tempfile
3222 }
3223
3224 test_31o() { # LU-2901
3225         test_mkdir $DIR/$tdir
3226         for LOOP in $(seq 100); do
3227                 rm -f $DIR/$tdir/$tfile*
3228                 for THREAD in $(seq 8); do
3229                         link_one $DIR/$tdir/$tfile.$LOOP &
3230                 done
3231                 wait
3232                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3233                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3234                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3235                         break || true
3236         done
3237 }
3238 run_test 31o "duplicate hard links with same filename"
3239
3240 test_31p() {
3241         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3242
3243         test_mkdir $DIR/$tdir
3244         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3245         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3246
3247         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3248                 error "open unlink test1 failed"
3249         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3250                 error "open unlink test2 failed"
3251
3252         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3253                 error "test1 still exists"
3254         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3255                 error "test2 still exists"
3256 }
3257 run_test 31p "remove of open striped directory"
3258
3259 cleanup_test32_mount() {
3260         local rc=0
3261         trap 0
3262         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3263         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3264         losetup -d $loopdev || true
3265         rm -rf $DIR/$tdir
3266         return $rc
3267 }
3268
3269 test_32a() {
3270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3271
3272         echo "== more mountpoints and symlinks ================="
3273         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3274         trap cleanup_test32_mount EXIT
3275         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3276         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3277                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3278         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3279                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3280         cleanup_test32_mount
3281 }
3282 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3283
3284 test_32b() {
3285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3286
3287         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3288         trap cleanup_test32_mount EXIT
3289         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3290         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3291                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3292         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3293                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3294         cleanup_test32_mount
3295 }
3296 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3297
3298 test_32c() {
3299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3300
3301         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3302         trap cleanup_test32_mount EXIT
3303         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3304         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3305                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3306         test_mkdir -p $DIR/$tdir/d2/test_dir
3307         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3308                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3309         cleanup_test32_mount
3310 }
3311 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3312
3313 test_32d() {
3314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3315
3316         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3317         trap cleanup_test32_mount EXIT
3318         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3319         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3320                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3321         test_mkdir -p $DIR/$tdir/d2/test_dir
3322         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3323                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3324         cleanup_test32_mount
3325 }
3326 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3327
3328 test_32e() {
3329         rm -fr $DIR/$tdir
3330         test_mkdir -p $DIR/$tdir/tmp
3331         local tmp_dir=$DIR/$tdir/tmp
3332         ln -s $DIR/$tdir $tmp_dir/symlink11
3333         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3334         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3335         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3336 }
3337 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3338
3339 test_32f() {
3340         rm -fr $DIR/$tdir
3341         test_mkdir -p $DIR/$tdir/tmp
3342         local tmp_dir=$DIR/$tdir/tmp
3343         ln -s $DIR/$tdir $tmp_dir/symlink11
3344         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3345         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3346         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3347 }
3348 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3349
3350 test_32g() {
3351         local tmp_dir=$DIR/$tdir/tmp
3352         test_mkdir -p $tmp_dir
3353         test_mkdir $DIR/${tdir}2
3354         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3355         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3356         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3357         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3358         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3359         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3360 }
3361 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3362
3363 test_32h() {
3364         rm -fr $DIR/$tdir $DIR/${tdir}2
3365         tmp_dir=$DIR/$tdir/tmp
3366         test_mkdir -p $tmp_dir
3367         test_mkdir $DIR/${tdir}2
3368         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3369         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3370         ls $tmp_dir/symlink12 || error "listing symlink12"
3371         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3372 }
3373 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3374
3375 test_32i() {
3376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3377
3378         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3379         trap cleanup_test32_mount EXIT
3380         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3381         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3382                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3383         touch $DIR/$tdir/test_file
3384         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3385                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3386         cleanup_test32_mount
3387 }
3388 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3389
3390 test_32j() {
3391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3392
3393         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3394         trap cleanup_test32_mount EXIT
3395         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3396         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3397                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3398         touch $DIR/$tdir/test_file
3399         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3400                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3401         cleanup_test32_mount
3402 }
3403 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3404
3405 test_32k() {
3406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3407
3408         rm -fr $DIR/$tdir
3409         trap cleanup_test32_mount EXIT
3410         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3411         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3412                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3413         test_mkdir -p $DIR/$tdir/d2
3414         touch $DIR/$tdir/d2/test_file || error "touch failed"
3415         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3416                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3417         cleanup_test32_mount
3418 }
3419 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3420
3421 test_32l() {
3422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3423
3424         rm -fr $DIR/$tdir
3425         trap cleanup_test32_mount EXIT
3426         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3427         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3428                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3429         test_mkdir -p $DIR/$tdir/d2
3430         touch $DIR/$tdir/d2/test_file || error "touch failed"
3431         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3432                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3433         cleanup_test32_mount
3434 }
3435 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3436
3437 test_32m() {
3438         rm -fr $DIR/d32m
3439         test_mkdir -p $DIR/d32m/tmp
3440         TMP_DIR=$DIR/d32m/tmp
3441         ln -s $DIR $TMP_DIR/symlink11
3442         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3443         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3444                 error "symlink11 not a link"
3445         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3446                 error "symlink01 not a link"
3447 }
3448 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3449
3450 test_32n() {
3451         rm -fr $DIR/d32n
3452         test_mkdir -p $DIR/d32n/tmp
3453         TMP_DIR=$DIR/d32n/tmp
3454         ln -s $DIR $TMP_DIR/symlink11
3455         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3456         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3457         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3458 }
3459 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3460
3461 test_32o() {
3462         touch $DIR/$tfile
3463         test_mkdir -p $DIR/d32o/tmp
3464         TMP_DIR=$DIR/d32o/tmp
3465         ln -s $DIR/$tfile $TMP_DIR/symlink12
3466         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3467         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3468                 error "symlink12 not a link"
3469         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3470         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3471                 error "$DIR/d32o/tmp/symlink12 not file type"
3472         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3473                 error "$DIR/d32o/symlink02 not file type"
3474 }
3475 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3476
3477 test_32p() {
3478         log 32p_1
3479         rm -fr $DIR/d32p
3480         log 32p_2
3481         rm -f $DIR/$tfile
3482         log 32p_3
3483         touch $DIR/$tfile
3484         log 32p_4
3485         test_mkdir -p $DIR/d32p/tmp
3486         log 32p_5
3487         TMP_DIR=$DIR/d32p/tmp
3488         log 32p_6
3489         ln -s $DIR/$tfile $TMP_DIR/symlink12
3490         log 32p_7
3491         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3492         log 32p_8
3493         cat $DIR/d32p/tmp/symlink12 ||
3494                 error "Can't open $DIR/d32p/tmp/symlink12"
3495         log 32p_9
3496         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3497         log 32p_10
3498 }
3499 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3500
3501 test_32q() {
3502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3503
3504         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3505         trap cleanup_test32_mount EXIT
3506         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3507         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3508         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3509                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3510         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3511         cleanup_test32_mount
3512 }
3513 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3514
3515 test_32r() {
3516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3517
3518         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3519         trap cleanup_test32_mount EXIT
3520         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3521         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3522         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3523                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3524         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3525         cleanup_test32_mount
3526 }
3527 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3528
3529 test_33aa() {
3530         rm -f $DIR/$tfile
3531         touch $DIR/$tfile
3532         chmod 444 $DIR/$tfile
3533         chown $RUNAS_ID $DIR/$tfile
3534         log 33_1
3535         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3536         log 33_2
3537 }
3538 run_test 33aa "write file with mode 444 (should return error)"
3539
3540 test_33a() {
3541         rm -fr $DIR/$tdir
3542         test_mkdir $DIR/$tdir
3543         chown $RUNAS_ID $DIR/$tdir
3544         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3545                 error "$RUNAS create $tdir/$tfile failed"
3546         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3547                 error "open RDWR" || true
3548 }
3549 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3550
3551 test_33b() {
3552         rm -fr $DIR/$tdir
3553         test_mkdir $DIR/$tdir
3554         chown $RUNAS_ID $DIR/$tdir
3555         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3556 }
3557 run_test 33b "test open file with malformed flags (No panic)"
3558
3559 test_33c() {
3560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3561         remote_ost_nodsh && skip "remote OST with nodsh"
3562
3563         local ostnum
3564         local ostname
3565         local write_bytes
3566         local all_zeros
3567
3568         all_zeros=:
3569         rm -fr $DIR/$tdir
3570         test_mkdir $DIR/$tdir
3571         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3572
3573         sync
3574         for ostnum in $(seq $OSTCOUNT); do
3575                 # test-framework's OST numbering is one-based, while Lustre's
3576                 # is zero-based
3577                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3578                 # Parsing llobdstat's output sucks; we could grep the /proc
3579                 # path, but that's likely to not be as portable as using the
3580                 # llobdstat utility.  So we parse lctl output instead.
3581                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3582                         obdfilter/$ostname/stats |
3583                         awk '/^write_bytes/ {print $7}' )
3584                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3585                 if (( ${write_bytes:-0} > 0 ))
3586                 then
3587                         all_zeros=false
3588                         break;
3589                 fi
3590         done
3591
3592         $all_zeros || return 0
3593
3594         # Write four bytes
3595         echo foo > $DIR/$tdir/bar
3596         # Really write them
3597         sync
3598
3599         # Total up write_bytes after writing.  We'd better find non-zeros.
3600         for ostnum in $(seq $OSTCOUNT); do
3601                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3602                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3603                         obdfilter/$ostname/stats |
3604                         awk '/^write_bytes/ {print $7}' )
3605                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3606                 if (( ${write_bytes:-0} > 0 ))
3607                 then
3608                         all_zeros=false
3609                         break;
3610                 fi
3611         done
3612
3613         if $all_zeros
3614         then
3615                 for ostnum in $(seq $OSTCOUNT); do
3616                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3617                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3618                         do_facet ost$ostnum lctl get_param -n \
3619                                 obdfilter/$ostname/stats
3620                 done
3621                 error "OST not keeping write_bytes stats (b22312)"
3622         fi
3623 }
3624 run_test 33c "test llobdstat and write_bytes"
3625
3626 test_33d() {
3627         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3629
3630         local MDTIDX=1
3631         local remote_dir=$DIR/$tdir/remote_dir
3632
3633         test_mkdir $DIR/$tdir
3634         $LFS mkdir -i $MDTIDX $remote_dir ||
3635                 error "create remote directory failed"
3636
3637         touch $remote_dir/$tfile
3638         chmod 444 $remote_dir/$tfile
3639         chown $RUNAS_ID $remote_dir/$tfile
3640
3641         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3642
3643         chown $RUNAS_ID $remote_dir
3644         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3645                                         error "create" || true
3646         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3647                                     error "open RDWR" || true
3648         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3649 }
3650 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3651
3652 test_33e() {
3653         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3654
3655         mkdir $DIR/$tdir
3656
3657         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3658         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3659         mkdir $DIR/$tdir/local_dir
3660
3661         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3662         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3663         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3664
3665         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3666                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3667
3668         rmdir $DIR/$tdir/* || error "rmdir failed"
3669
3670         umask 777
3671         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3672         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3673         mkdir $DIR/$tdir/local_dir
3674
3675         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3676         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3677         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3678
3679         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3680                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3681
3682         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3683
3684         umask 000
3685         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3686         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3687         mkdir $DIR/$tdir/local_dir
3688
3689         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3690         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3691         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3692
3693         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3694                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3695 }
3696 run_test 33e "mkdir and striped directory should have same mode"
3697
3698 cleanup_33f() {
3699         trap 0
3700         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3701 }
3702
3703 test_33f() {
3704         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3705         remote_mds_nodsh && skip "remote MDS with nodsh"
3706
3707         mkdir $DIR/$tdir
3708         chmod go+rwx $DIR/$tdir
3709         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3710         trap cleanup_33f EXIT
3711
3712         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3713                 error "cannot create striped directory"
3714
3715         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3716                 error "cannot create files in striped directory"
3717
3718         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3719                 error "cannot remove files in striped directory"
3720
3721         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3722                 error "cannot remove striped directory"
3723
3724         cleanup_33f
3725 }
3726 run_test 33f "nonroot user can create, access, and remove a striped directory"
3727
3728 test_33g() {
3729         mkdir -p $DIR/$tdir/dir2
3730
3731         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3732         echo $err
3733         [[ $err =~ "exists" ]] || error "Not exists error"
3734 }
3735 run_test 33g "nonroot user create already existing root created file"
3736
3737 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3738 test_34a() {
3739         rm -f $DIR/f34
3740         $MCREATE $DIR/f34 || error "mcreate failed"
3741         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3742                 error "getstripe failed"
3743         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3744         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3745                 error "getstripe failed"
3746         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3747                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3748 }
3749 run_test 34a "truncate file that has not been opened ==========="
3750
3751 test_34b() {
3752         [ ! -f $DIR/f34 ] && test_34a
3753         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3754                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3755         $OPENFILE -f O_RDONLY $DIR/f34
3756         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3757                 error "getstripe failed"
3758         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3759                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3760 }
3761 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3762
3763 test_34c() {
3764         [ ! -f $DIR/f34 ] && test_34a
3765         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3766                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3767         $OPENFILE -f O_RDWR $DIR/f34
3768         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3769                 error "$LFS getstripe failed"
3770         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3771                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3772 }
3773 run_test 34c "O_RDWR opening file-with-size works =============="
3774
3775 test_34d() {
3776         [ ! -f $DIR/f34 ] && test_34a
3777         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3778                 error "dd failed"
3779         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3780                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3781         rm $DIR/f34
3782 }
3783 run_test 34d "write to sparse file ============================="
3784
3785 test_34e() {
3786         rm -f $DIR/f34e
3787         $MCREATE $DIR/f34e || error "mcreate failed"
3788         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3789         $CHECKSTAT -s 1000 $DIR/f34e ||
3790                 error "Size of $DIR/f34e not equal to 1000 bytes"
3791         $OPENFILE -f O_RDWR $DIR/f34e
3792         $CHECKSTAT -s 1000 $DIR/f34e ||
3793                 error "Size of $DIR/f34e not equal to 1000 bytes"
3794 }
3795 run_test 34e "create objects, some with size and some without =="
3796
3797 test_34f() { # bug 6242, 6243
3798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3799
3800         SIZE34F=48000
3801         rm -f $DIR/f34f
3802         $MCREATE $DIR/f34f || error "mcreate failed"
3803         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3804         dd if=$DIR/f34f of=$TMP/f34f
3805         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3806         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3807         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3808         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3809         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3810 }
3811 run_test 34f "read from a file with no objects until EOF ======="
3812
3813 test_34g() {
3814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3815
3816         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3817                 error "dd failed"
3818         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3819         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3820                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3821         cancel_lru_locks osc
3822         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3823                 error "wrong size after lock cancel"
3824
3825         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3826         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3827                 error "expanding truncate failed"
3828         cancel_lru_locks osc
3829         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3830                 error "wrong expanded size after lock cancel"
3831 }
3832 run_test 34g "truncate long file ==============================="
3833
3834 test_34h() {
3835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3836
3837         local gid=10
3838         local sz=1000
3839
3840         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3841         sync # Flush the cache so that multiop below does not block on cache
3842              # flush when getting the group lock
3843         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3844         MULTIPID=$!
3845
3846         # Since just timed wait is not good enough, let's do a sync write
3847         # that way we are sure enough time for a roundtrip + processing
3848         # passed + 2 seconds of extra margin.
3849         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3850         rm $DIR/${tfile}-1
3851         sleep 2
3852
3853         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3854                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3855                 kill -9 $MULTIPID
3856         fi
3857         wait $MULTIPID
3858         local nsz=`stat -c %s $DIR/$tfile`
3859         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3860 }
3861 run_test 34h "ftruncate file under grouplock should not block"
3862
3863 test_35a() {
3864         cp /bin/sh $DIR/f35a
3865         chmod 444 $DIR/f35a
3866         chown $RUNAS_ID $DIR/f35a
3867         $RUNAS $DIR/f35a && error || true
3868         rm $DIR/f35a
3869 }
3870 run_test 35a "exec file with mode 444 (should return and not leak)"
3871
3872 test_36a() {
3873         rm -f $DIR/f36
3874         utime $DIR/f36 || error "utime failed for MDS"
3875 }
3876 run_test 36a "MDS utime check (mknod, utime)"
3877
3878 test_36b() {
3879         echo "" > $DIR/f36
3880         utime $DIR/f36 || error "utime failed for OST"
3881 }
3882 run_test 36b "OST utime check (open, utime)"
3883
3884 test_36c() {
3885         rm -f $DIR/d36/f36
3886         test_mkdir $DIR/d36
3887         chown $RUNAS_ID $DIR/d36
3888         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3889 }
3890 run_test 36c "non-root MDS utime check (mknod, utime)"
3891
3892 test_36d() {
3893         [ ! -d $DIR/d36 ] && test_36c
3894         echo "" > $DIR/d36/f36
3895         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3896 }
3897 run_test 36d "non-root OST utime check (open, utime)"
3898
3899 test_36e() {
3900         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3901
3902         test_mkdir $DIR/$tdir
3903         touch $DIR/$tdir/$tfile
3904         $RUNAS utime $DIR/$tdir/$tfile &&
3905                 error "utime worked, expected failure" || true
3906 }
3907 run_test 36e "utime on non-owned file (should return error)"
3908
3909 subr_36fh() {
3910         local fl="$1"
3911         local LANG_SAVE=$LANG
3912         local LC_LANG_SAVE=$LC_LANG
3913         export LANG=C LC_LANG=C # for date language
3914
3915         DATESTR="Dec 20  2000"
3916         test_mkdir $DIR/$tdir
3917         lctl set_param fail_loc=$fl
3918         date; date +%s
3919         cp /etc/hosts $DIR/$tdir/$tfile
3920         sync & # write RPC generated with "current" inode timestamp, but delayed
3921         sleep 1
3922         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3923         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3924         cancel_lru_locks $OSC
3925         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3926         date; date +%s
3927         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3928                 echo "BEFORE: $LS_BEFORE" && \
3929                 echo "AFTER : $LS_AFTER" && \
3930                 echo "WANT  : $DATESTR" && \
3931                 error "$DIR/$tdir/$tfile timestamps changed" || true
3932
3933         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3934 }
3935
3936 test_36f() {
3937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3938
3939         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3940         subr_36fh "0x80000214"
3941 }
3942 run_test 36f "utime on file racing with OST BRW write =========="
3943
3944 test_36g() {
3945         remote_ost_nodsh && skip "remote OST with nodsh"
3946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3947         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3948                 skip "Need MDS version at least 2.12.51"
3949
3950         local fmd_max_age
3951         local fmd
3952         local facet="ost1"
3953         local tgt="obdfilter"
3954
3955         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3956
3957         test_mkdir $DIR/$tdir
3958         fmd_max_age=$(do_facet $facet \
3959                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3960                 head -n 1")
3961
3962         echo "FMD max age: ${fmd_max_age}s"
3963         touch $DIR/$tdir/$tfile
3964         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3965                 gawk '{cnt=cnt+$1}  END{print cnt}')
3966         echo "FMD before: $fmd"
3967         [[ $fmd == 0 ]] &&
3968                 error "FMD wasn't create by touch"
3969         sleep $((fmd_max_age + 12))
3970         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3971                 gawk '{cnt=cnt+$1}  END{print cnt}')
3972         echo "FMD after: $fmd"
3973         [[ $fmd == 0 ]] ||
3974                 error "FMD wasn't expired by ping"
3975 }
3976 run_test 36g "FMD cache expiry ====================="
3977
3978 test_36h() {
3979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3980
3981         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3982         subr_36fh "0x80000227"
3983 }
3984 run_test 36h "utime on file racing with OST BRW write =========="
3985
3986 test_36i() {
3987         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3988
3989         test_mkdir $DIR/$tdir
3990         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3991
3992         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3993         local new_mtime=$((mtime + 200))
3994
3995         #change Modify time of striped dir
3996         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3997                         error "change mtime failed"
3998
3999         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4000
4001         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4002 }
4003 run_test 36i "change mtime on striped directory"
4004
4005 # test_37 - duplicate with tests 32q 32r
4006
4007 test_38() {
4008         local file=$DIR/$tfile
4009         touch $file
4010         openfile -f O_DIRECTORY $file
4011         local RC=$?
4012         local ENOTDIR=20
4013         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4014         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4015 }
4016 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4017
4018 test_39a() { # was test_39
4019         touch $DIR/$tfile
4020         touch $DIR/${tfile}2
4021 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4022 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4023 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4024         sleep 2
4025         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4026         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4027                 echo "mtime"
4028                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4029                 echo "atime"
4030                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4031                 echo "ctime"
4032                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4033                 error "O_TRUNC didn't change timestamps"
4034         fi
4035 }
4036 run_test 39a "mtime changed on create"
4037
4038 test_39b() {
4039         test_mkdir -c1 $DIR/$tdir
4040         cp -p /etc/passwd $DIR/$tdir/fopen
4041         cp -p /etc/passwd $DIR/$tdir/flink
4042         cp -p /etc/passwd $DIR/$tdir/funlink
4043         cp -p /etc/passwd $DIR/$tdir/frename
4044         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4045
4046         sleep 1
4047         echo "aaaaaa" >> $DIR/$tdir/fopen
4048         echo "aaaaaa" >> $DIR/$tdir/flink
4049         echo "aaaaaa" >> $DIR/$tdir/funlink
4050         echo "aaaaaa" >> $DIR/$tdir/frename
4051
4052         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4053         local link_new=`stat -c %Y $DIR/$tdir/flink`
4054         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4055         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4056
4057         cat $DIR/$tdir/fopen > /dev/null
4058         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4059         rm -f $DIR/$tdir/funlink2
4060         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4061
4062         for (( i=0; i < 2; i++ )) ; do
4063                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4064                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4065                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4066                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4067
4068                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4069                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4070                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4071                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4072
4073                 cancel_lru_locks $OSC
4074                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4075         done
4076 }
4077 run_test 39b "mtime change on open, link, unlink, rename  ======"
4078
4079 # this should be set to past
4080 TEST_39_MTIME=`date -d "1 year ago" +%s`
4081
4082 # bug 11063
4083 test_39c() {
4084         touch $DIR1/$tfile
4085         sleep 2
4086         local mtime0=`stat -c %Y $DIR1/$tfile`
4087
4088         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4089         local mtime1=`stat -c %Y $DIR1/$tfile`
4090         [ "$mtime1" = $TEST_39_MTIME ] || \
4091                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4092
4093         local d1=`date +%s`
4094         echo hello >> $DIR1/$tfile
4095         local d2=`date +%s`
4096         local mtime2=`stat -c %Y $DIR1/$tfile`
4097         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4098                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4099
4100         mv $DIR1/$tfile $DIR1/$tfile-1
4101
4102         for (( i=0; i < 2; i++ )) ; do
4103                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4104                 [ "$mtime2" = "$mtime3" ] || \
4105                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4106
4107                 cancel_lru_locks $OSC
4108                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4109         done
4110 }
4111 run_test 39c "mtime change on rename ==========================="
4112
4113 # bug 21114
4114 test_39d() {
4115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4116
4117         touch $DIR1/$tfile
4118         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4119
4120         for (( i=0; i < 2; i++ )) ; do
4121                 local mtime=`stat -c %Y $DIR1/$tfile`
4122                 [ $mtime = $TEST_39_MTIME ] || \
4123                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4124
4125                 cancel_lru_locks $OSC
4126                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4127         done
4128 }
4129 run_test 39d "create, utime, stat =============================="
4130
4131 # bug 21114
4132 test_39e() {
4133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4134
4135         touch $DIR1/$tfile
4136         local mtime1=`stat -c %Y $DIR1/$tfile`
4137
4138         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4139
4140         for (( i=0; i < 2; i++ )) ; do
4141                 local mtime2=`stat -c %Y $DIR1/$tfile`
4142                 [ $mtime2 = $TEST_39_MTIME ] || \
4143                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4144
4145                 cancel_lru_locks $OSC
4146                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4147         done
4148 }
4149 run_test 39e "create, stat, utime, stat ========================"
4150
4151 # bug 21114
4152 test_39f() {
4153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4154
4155         touch $DIR1/$tfile
4156         mtime1=`stat -c %Y $DIR1/$tfile`
4157
4158         sleep 2
4159         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4160
4161         for (( i=0; i < 2; i++ )) ; do
4162                 local mtime2=`stat -c %Y $DIR1/$tfile`
4163                 [ $mtime2 = $TEST_39_MTIME ] || \
4164                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4165
4166                 cancel_lru_locks $OSC
4167                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4168         done
4169 }
4170 run_test 39f "create, stat, sleep, utime, stat ================="
4171
4172 # bug 11063
4173 test_39g() {
4174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4175
4176         echo hello >> $DIR1/$tfile
4177         local mtime1=`stat -c %Y $DIR1/$tfile`
4178
4179         sleep 2
4180         chmod o+r $DIR1/$tfile
4181
4182         for (( i=0; i < 2; i++ )) ; do
4183                 local mtime2=`stat -c %Y $DIR1/$tfile`
4184                 [ "$mtime1" = "$mtime2" ] || \
4185                         error "lost mtime: $mtime2, should be $mtime1"
4186
4187                 cancel_lru_locks $OSC
4188                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4189         done
4190 }
4191 run_test 39g "write, chmod, stat ==============================="
4192
4193 # bug 11063
4194 test_39h() {
4195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4196
4197         touch $DIR1/$tfile
4198         sleep 1
4199
4200         local d1=`date`
4201         echo hello >> $DIR1/$tfile
4202         local mtime1=`stat -c %Y $DIR1/$tfile`
4203
4204         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4205         local d2=`date`
4206         if [ "$d1" != "$d2" ]; then
4207                 echo "write and touch not within one second"
4208         else
4209                 for (( i=0; i < 2; i++ )) ; do
4210                         local mtime2=`stat -c %Y $DIR1/$tfile`
4211                         [ "$mtime2" = $TEST_39_MTIME ] || \
4212                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4213
4214                         cancel_lru_locks $OSC
4215                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4216                 done
4217         fi
4218 }
4219 run_test 39h "write, utime within one second, stat ============="
4220
4221 test_39i() {
4222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4223
4224         touch $DIR1/$tfile
4225         sleep 1
4226
4227         echo hello >> $DIR1/$tfile
4228         local mtime1=`stat -c %Y $DIR1/$tfile`
4229
4230         mv $DIR1/$tfile $DIR1/$tfile-1
4231
4232         for (( i=0; i < 2; i++ )) ; do
4233                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4234
4235                 [ "$mtime1" = "$mtime2" ] || \
4236                         error "lost mtime: $mtime2, should be $mtime1"
4237
4238                 cancel_lru_locks $OSC
4239                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4240         done
4241 }
4242 run_test 39i "write, rename, stat =============================="
4243
4244 test_39j() {
4245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4246
4247         start_full_debug_logging
4248         touch $DIR1/$tfile
4249         sleep 1
4250
4251         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4252         lctl set_param fail_loc=0x80000412
4253         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4254                 error "multiop failed"
4255         local multipid=$!
4256         local mtime1=`stat -c %Y $DIR1/$tfile`
4257
4258         mv $DIR1/$tfile $DIR1/$tfile-1
4259
4260         kill -USR1 $multipid
4261         wait $multipid || error "multiop close failed"
4262
4263         for (( i=0; i < 2; i++ )) ; do
4264                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4265                 [ "$mtime1" = "$mtime2" ] ||
4266                         error "mtime is lost on close: $mtime2, " \
4267                               "should be $mtime1"
4268
4269                 cancel_lru_locks
4270                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4271         done
4272         lctl set_param fail_loc=0
4273         stop_full_debug_logging
4274 }
4275 run_test 39j "write, rename, close, stat ======================="
4276
4277 test_39k() {
4278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4279
4280         touch $DIR1/$tfile
4281         sleep 1
4282
4283         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4284         local multipid=$!
4285         local mtime1=`stat -c %Y $DIR1/$tfile`
4286
4287         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4288
4289         kill -USR1 $multipid
4290         wait $multipid || error "multiop close failed"
4291
4292         for (( i=0; i < 2; i++ )) ; do
4293                 local mtime2=`stat -c %Y $DIR1/$tfile`
4294
4295                 [ "$mtime2" = $TEST_39_MTIME ] || \
4296                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4297
4298                 cancel_lru_locks
4299                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4300         done
4301 }
4302 run_test 39k "write, utime, close, stat ========================"
4303
4304 # this should be set to future
4305 TEST_39_ATIME=`date -d "1 year" +%s`
4306
4307 test_39l() {
4308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4309         remote_mds_nodsh && skip "remote MDS with nodsh"
4310
4311         local atime_diff=$(do_facet $SINGLEMDS \
4312                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4313         rm -rf $DIR/$tdir
4314         mkdir -p $DIR/$tdir
4315
4316         # test setting directory atime to future
4317         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4318         local atime=$(stat -c %X $DIR/$tdir)
4319         [ "$atime" = $TEST_39_ATIME ] ||
4320                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4321
4322         # test setting directory atime from future to now
4323         local now=$(date +%s)
4324         touch -a -d @$now $DIR/$tdir
4325
4326         atime=$(stat -c %X $DIR/$tdir)
4327         [ "$atime" -eq "$now"  ] ||
4328                 error "atime is not updated from future: $atime, $now"
4329
4330         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4331         sleep 3
4332
4333         # test setting directory atime when now > dir atime + atime_diff
4334         local d1=$(date +%s)
4335         ls $DIR/$tdir
4336         local d2=$(date +%s)
4337         cancel_lru_locks mdc
4338         atime=$(stat -c %X $DIR/$tdir)
4339         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4340                 error "atime is not updated  : $atime, should be $d2"
4341
4342         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4343         sleep 3
4344
4345         # test not setting directory atime when now < dir atime + atime_diff
4346         ls $DIR/$tdir
4347         cancel_lru_locks mdc
4348         atime=$(stat -c %X $DIR/$tdir)
4349         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4350                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4351
4352         do_facet $SINGLEMDS \
4353                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4354 }
4355 run_test 39l "directory atime update ==========================="
4356
4357 test_39m() {
4358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4359
4360         touch $DIR1/$tfile
4361         sleep 2
4362         local far_past_mtime=$(date -d "May 29 1953" +%s)
4363         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4364
4365         touch -m -d @$far_past_mtime $DIR1/$tfile
4366         touch -a -d @$far_past_atime $DIR1/$tfile
4367
4368         for (( i=0; i < 2; i++ )) ; do
4369                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4370                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4371                         error "atime or mtime set incorrectly"
4372
4373                 cancel_lru_locks $OSC
4374                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4375         done
4376 }
4377 run_test 39m "test atime and mtime before 1970"
4378
4379 test_39n() { # LU-3832
4380         remote_mds_nodsh && skip "remote MDS with nodsh"
4381
4382         local atime_diff=$(do_facet $SINGLEMDS \
4383                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4384         local atime0
4385         local atime1
4386         local atime2
4387
4388         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4389
4390         rm -rf $DIR/$tfile
4391         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4392         atime0=$(stat -c %X $DIR/$tfile)
4393
4394         sleep 5
4395         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4396         atime1=$(stat -c %X $DIR/$tfile)
4397
4398         sleep 5
4399         cancel_lru_locks mdc
4400         cancel_lru_locks osc
4401         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4402         atime2=$(stat -c %X $DIR/$tfile)
4403
4404         do_facet $SINGLEMDS \
4405                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4406
4407         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4408         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4409 }
4410 run_test 39n "check that O_NOATIME is honored"
4411
4412 test_39o() {
4413         TESTDIR=$DIR/$tdir/$tfile
4414         [ -e $TESTDIR ] && rm -rf $TESTDIR
4415         mkdir -p $TESTDIR
4416         cd $TESTDIR
4417         links1=2
4418         ls
4419         mkdir a b
4420         ls
4421         links2=$(stat -c %h .)
4422         [ $(($links1 + 2)) != $links2 ] &&
4423                 error "wrong links count $(($links1 + 2)) != $links2"
4424         rmdir b
4425         links3=$(stat -c %h .)
4426         [ $(($links1 + 1)) != $links3 ] &&
4427                 error "wrong links count $links1 != $links3"
4428         return 0
4429 }
4430 run_test 39o "directory cached attributes updated after create"
4431
4432 test_39p() {
4433         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4434
4435         local MDTIDX=1
4436         TESTDIR=$DIR/$tdir/$tdir
4437         [ -e $TESTDIR ] && rm -rf $TESTDIR
4438         test_mkdir -p $TESTDIR
4439         cd $TESTDIR
4440         links1=2
4441         ls
4442         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4443         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4444         ls
4445         links2=$(stat -c %h .)
4446         [ $(($links1 + 2)) != $links2 ] &&
4447                 error "wrong links count $(($links1 + 2)) != $links2"
4448         rmdir remote_dir2
4449         links3=$(stat -c %h .)
4450         [ $(($links1 + 1)) != $links3 ] &&
4451                 error "wrong links count $links1 != $links3"
4452         return 0
4453 }
4454 run_test 39p "remote directory cached attributes updated after create ========"
4455
4456
4457 test_39q() { # LU-8041
4458         local testdir=$DIR/$tdir
4459         mkdir -p $testdir
4460         multiop_bg_pause $testdir D_c || error "multiop failed"
4461         local multipid=$!
4462         cancel_lru_locks mdc
4463         kill -USR1 $multipid
4464         local atime=$(stat -c %X $testdir)
4465         [ "$atime" -ne 0 ] || error "atime is zero"
4466 }
4467 run_test 39q "close won't zero out atime"
4468
4469 test_40() {
4470         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4471         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4472                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4473         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4474                 error "$tfile is not 4096 bytes in size"
4475 }
4476 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4477
4478 test_41() {
4479         # bug 1553
4480         small_write $DIR/f41 18
4481 }
4482 run_test 41 "test small file write + fstat ====================="
4483
4484 count_ost_writes() {
4485         lctl get_param -n ${OSC}.*.stats |
4486                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4487                         END { printf("%0.0f", writes) }'
4488 }
4489
4490 # decent default
4491 WRITEBACK_SAVE=500
4492 DIRTY_RATIO_SAVE=40
4493 MAX_DIRTY_RATIO=50
4494 BG_DIRTY_RATIO_SAVE=10
4495 MAX_BG_DIRTY_RATIO=25
4496
4497 start_writeback() {
4498         trap 0
4499         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4500         # dirty_ratio, dirty_background_ratio
4501         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4502                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4503                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4504                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4505         else
4506                 # if file not here, we are a 2.4 kernel
4507                 kill -CONT `pidof kupdated`
4508         fi
4509 }
4510
4511 stop_writeback() {
4512         # setup the trap first, so someone cannot exit the test at the
4513         # exact wrong time and mess up a machine
4514         trap start_writeback EXIT
4515         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4516         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4517                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4518                 sysctl -w vm.dirty_writeback_centisecs=0
4519                 sysctl -w vm.dirty_writeback_centisecs=0
4520                 # save and increase /proc/sys/vm/dirty_ratio
4521                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4522                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4523                 # save and increase /proc/sys/vm/dirty_background_ratio
4524                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4525                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4526         else
4527                 # if file not here, we are a 2.4 kernel
4528                 kill -STOP `pidof kupdated`
4529         fi
4530 }
4531
4532 # ensure that all stripes have some grant before we test client-side cache
4533 setup_test42() {
4534         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4535                 dd if=/dev/zero of=$i bs=4k count=1
4536                 rm $i
4537         done
4538 }
4539
4540 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4541 # file truncation, and file removal.
4542 test_42a() {
4543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4544
4545         setup_test42
4546         cancel_lru_locks $OSC
4547         stop_writeback
4548         sync; sleep 1; sync # just to be safe
4549         BEFOREWRITES=`count_ost_writes`
4550         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4551         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4552         AFTERWRITES=`count_ost_writes`
4553         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4554                 error "$BEFOREWRITES < $AFTERWRITES"
4555         start_writeback
4556 }
4557 run_test 42a "ensure that we don't flush on close"
4558
4559 test_42b() {
4560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4561
4562         setup_test42
4563         cancel_lru_locks $OSC
4564         stop_writeback
4565         sync
4566         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4567         BEFOREWRITES=$(count_ost_writes)
4568         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4569         AFTERWRITES=$(count_ost_writes)
4570         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4571                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4572         fi
4573         BEFOREWRITES=$(count_ost_writes)
4574         sync || error "sync: $?"
4575         AFTERWRITES=$(count_ost_writes)
4576         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4577                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4578         fi
4579         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4580         start_writeback
4581         return 0
4582 }
4583 run_test 42b "test destroy of file with cached dirty data ======"
4584
4585 # if these tests just want to test the effect of truncation,
4586 # they have to be very careful.  consider:
4587 # - the first open gets a {0,EOF}PR lock
4588 # - the first write conflicts and gets a {0, count-1}PW
4589 # - the rest of the writes are under {count,EOF}PW
4590 # - the open for truncate tries to match a {0,EOF}PR
4591 #   for the filesize and cancels the PWs.
4592 # any number of fixes (don't get {0,EOF} on open, match
4593 # composite locks, do smarter file size management) fix
4594 # this, but for now we want these tests to verify that
4595 # the cancellation with truncate intent works, so we
4596 # start the file with a full-file pw lock to match against
4597 # until the truncate.
4598 trunc_test() {
4599         test=$1
4600         file=$DIR/$test
4601         offset=$2
4602         cancel_lru_locks $OSC
4603         stop_writeback
4604         # prime the file with 0,EOF PW to match
4605         touch $file
4606         $TRUNCATE $file 0
4607         sync; sync
4608         # now the real test..
4609         dd if=/dev/zero of=$file bs=1024 count=100
4610         BEFOREWRITES=`count_ost_writes`
4611         $TRUNCATE $file $offset
4612         cancel_lru_locks $OSC
4613         AFTERWRITES=`count_ost_writes`
4614         start_writeback
4615 }
4616
4617 test_42c() {
4618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4619
4620         trunc_test 42c 1024
4621         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4622                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4623         rm $file
4624 }
4625 run_test 42c "test partial truncate of file with cached dirty data"
4626
4627 test_42d() {
4628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4629
4630         trunc_test 42d 0
4631         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4632                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4633         rm $file
4634 }
4635 run_test 42d "test complete truncate of file with cached dirty data"
4636
4637 test_42e() { # bug22074
4638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4639
4640         local TDIR=$DIR/${tdir}e
4641         local pages=16 # hardcoded 16 pages, don't change it.
4642         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4643         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4644         local max_dirty_mb
4645         local warmup_files
4646
4647         test_mkdir $DIR/${tdir}e
4648         $LFS setstripe -c 1 $TDIR
4649         createmany -o $TDIR/f $files
4650
4651         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4652
4653         # we assume that with $OSTCOUNT files, at least one of them will
4654         # be allocated on OST0.
4655         warmup_files=$((OSTCOUNT * max_dirty_mb))
4656         createmany -o $TDIR/w $warmup_files
4657
4658         # write a large amount of data into one file and sync, to get good
4659         # avail_grant number from OST.
4660         for ((i=0; i<$warmup_files; i++)); do
4661                 idx=$($LFS getstripe -i $TDIR/w$i)
4662                 [ $idx -ne 0 ] && continue
4663                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4664                 break
4665         done
4666         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4667         sync
4668         $LCTL get_param $proc_osc0/cur_dirty_bytes
4669         $LCTL get_param $proc_osc0/cur_grant_bytes
4670
4671         # create as much dirty pages as we can while not to trigger the actual
4672         # RPCs directly. but depends on the env, VFS may trigger flush during this
4673         # period, hopefully we are good.
4674         for ((i=0; i<$warmup_files; i++)); do
4675                 idx=$($LFS getstripe -i $TDIR/w$i)
4676                 [ $idx -ne 0 ] && continue
4677                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4678         done
4679         $LCTL get_param $proc_osc0/cur_dirty_bytes
4680         $LCTL get_param $proc_osc0/cur_grant_bytes
4681
4682         # perform the real test
4683         $LCTL set_param $proc_osc0/rpc_stats 0
4684         for ((;i<$files; i++)); do
4685                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4686                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4687         done
4688         sync
4689         $LCTL get_param $proc_osc0/rpc_stats
4690
4691         local percent=0
4692         local have_ppr=false
4693         $LCTL get_param $proc_osc0/rpc_stats |
4694                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4695                         # skip lines until we are at the RPC histogram data
4696                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4697                         $have_ppr || continue
4698
4699                         # we only want the percent stat for < 16 pages
4700                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4701
4702                         percent=$((percent + WPCT))
4703                         if [[ $percent -gt 15 ]]; then
4704                                 error "less than 16-pages write RPCs" \
4705                                       "$percent% > 15%"
4706                                 break
4707                         fi
4708                 done
4709         rm -rf $TDIR
4710 }
4711 run_test 42e "verify sub-RPC writes are not done synchronously"
4712
4713 test_43A() { # was test_43
4714         test_mkdir $DIR/$tdir
4715         cp -p /bin/ls $DIR/$tdir/$tfile
4716         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4717         pid=$!
4718         # give multiop a chance to open
4719         sleep 1
4720
4721         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4722         kill -USR1 $pid
4723 }
4724 run_test 43A "execution of file opened for write should return -ETXTBSY"
4725
4726 test_43a() {
4727         test_mkdir $DIR/$tdir
4728         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4729         $DIR/$tdir/sleep 60 &
4730         SLEEP_PID=$!
4731         # Make sure exec of $tdir/sleep wins race with truncate
4732         sleep 1
4733         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4734         kill $SLEEP_PID
4735 }
4736 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4737
4738 test_43b() {
4739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4740
4741         test_mkdir $DIR/$tdir
4742         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4743         $DIR/$tdir/sleep 60 &
4744         SLEEP_PID=$!
4745         # Make sure exec of $tdir/sleep wins race with truncate
4746         sleep 1
4747         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4748         kill $SLEEP_PID
4749 }
4750 run_test 43b "truncate of file being executed should return -ETXTBSY"
4751
4752 test_43c() {
4753         local testdir="$DIR/$tdir"
4754         test_mkdir $testdir
4755         cp $SHELL $testdir/
4756         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4757                 ( cd $testdir && md5sum -c )
4758 }
4759 run_test 43c "md5sum of copy into lustre"
4760
4761 test_44A() { # was test_44
4762         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4763
4764         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4765         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4766 }
4767 run_test 44A "zero length read from a sparse stripe"
4768
4769 test_44a() {
4770         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4771                 awk '{ print $2 }')
4772         [ -z "$nstripe" ] && skip "can't get stripe info"
4773         [[ $nstripe -gt $OSTCOUNT ]] &&
4774                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4775
4776         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4777                 awk '{ print $2 }')
4778         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4779                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4780                         awk '{ print $2 }')
4781         fi
4782
4783         OFFSETS="0 $((stride/2)) $((stride-1))"
4784         for offset in $OFFSETS; do
4785                 for i in $(seq 0 $((nstripe-1))); do
4786                         local GLOBALOFFSETS=""
4787                         # size in Bytes
4788                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4789                         local myfn=$DIR/d44a-$size
4790                         echo "--------writing $myfn at $size"
4791                         ll_sparseness_write $myfn $size ||
4792                                 error "ll_sparseness_write"
4793                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4794                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4795                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4796
4797                         for j in $(seq 0 $((nstripe-1))); do
4798                                 # size in Bytes
4799                                 size=$((((j + $nstripe )*$stride + $offset)))
4800                                 ll_sparseness_write $myfn $size ||
4801                                         error "ll_sparseness_write"
4802                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4803                         done
4804                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4805                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4806                         rm -f $myfn
4807                 done
4808         done
4809 }
4810 run_test 44a "test sparse pwrite ==============================="
4811
4812 dirty_osc_total() {
4813         tot=0
4814         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4815                 tot=$(($tot + $d))
4816         done
4817         echo $tot
4818 }
4819 do_dirty_record() {
4820         before=`dirty_osc_total`
4821         echo executing "\"$*\""
4822         eval $*
4823         after=`dirty_osc_total`
4824         echo before $before, after $after
4825 }
4826 test_45() {
4827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4828
4829         f="$DIR/f45"
4830         # Obtain grants from OST if it supports it
4831         echo blah > ${f}_grant
4832         stop_writeback
4833         sync
4834         do_dirty_record "echo blah > $f"
4835         [[ $before -eq $after ]] && error "write wasn't cached"
4836         do_dirty_record "> $f"
4837         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4838         do_dirty_record "echo blah > $f"
4839         [[ $before -eq $after ]] && error "write wasn't cached"
4840         do_dirty_record "sync"
4841         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4842         do_dirty_record "echo blah > $f"
4843         [[ $before -eq $after ]] && error "write wasn't cached"
4844         do_dirty_record "cancel_lru_locks osc"
4845         [[ $before -gt $after ]] ||
4846                 error "lock cancellation didn't lower dirty count"
4847         start_writeback
4848 }
4849 run_test 45 "osc io page accounting ============================"
4850
4851 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4852 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4853 # objects offset and an assert hit when an rpc was built with 1023's mapped
4854 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4855 test_46() {
4856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4857
4858         f="$DIR/f46"
4859         stop_writeback
4860         sync
4861         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4862         sync
4863         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4864         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4865         sync
4866         start_writeback
4867 }
4868 run_test 46 "dirtying a previously written page ================"
4869
4870 # test_47 is removed "Device nodes check" is moved to test_28
4871
4872 test_48a() { # bug 2399
4873         [ "$mds1_FSTYPE" = "zfs" ] &&
4874         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4875                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4876
4877         test_mkdir $DIR/$tdir
4878         cd $DIR/$tdir
4879         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4880         test_mkdir $DIR/$tdir
4881         touch foo || error "'touch foo' failed after recreating cwd"
4882         test_mkdir bar
4883         touch .foo || error "'touch .foo' failed after recreating cwd"
4884         test_mkdir .bar
4885         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4886         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4887         cd . || error "'cd .' failed after recreating cwd"
4888         mkdir . && error "'mkdir .' worked after recreating cwd"
4889         rmdir . && error "'rmdir .' worked after recreating cwd"
4890         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4891         cd .. || error "'cd ..' failed after recreating cwd"
4892 }
4893 run_test 48a "Access renamed working dir (should return errors)="
4894
4895 test_48b() { # bug 2399
4896         rm -rf $DIR/$tdir
4897         test_mkdir $DIR/$tdir
4898         cd $DIR/$tdir
4899         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4900         touch foo && error "'touch foo' worked after removing cwd"
4901         mkdir foo && error "'mkdir foo' worked after removing cwd"
4902         touch .foo && error "'touch .foo' worked after removing cwd"
4903         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4904         ls . > /dev/null && error "'ls .' worked after removing cwd"
4905         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4906         mkdir . && error "'mkdir .' worked after removing cwd"
4907         rmdir . && error "'rmdir .' worked after removing cwd"
4908         ln -s . foo && error "'ln -s .' worked after removing cwd"
4909         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4910 }
4911 run_test 48b "Access removed working dir (should return errors)="
4912
4913 test_48c() { # bug 2350
4914         #lctl set_param debug=-1
4915         #set -vx
4916         rm -rf $DIR/$tdir
4917         test_mkdir -p $DIR/$tdir/dir
4918         cd $DIR/$tdir/dir
4919         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4920         $TRACE touch foo && error "touch foo worked after removing cwd"
4921         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4922         touch .foo && error "touch .foo worked after removing cwd"
4923         mkdir .foo && error "mkdir .foo worked after removing cwd"
4924         $TRACE ls . && error "'ls .' worked after removing cwd"
4925         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4926         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4927         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4928         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4929         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4930 }
4931 run_test 48c "Access removed working subdir (should return errors)"
4932
4933 test_48d() { # bug 2350
4934         #lctl set_param debug=-1
4935         #set -vx
4936         rm -rf $DIR/$tdir
4937         test_mkdir -p $DIR/$tdir/dir
4938         cd $DIR/$tdir/dir
4939         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4940         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4941         $TRACE touch foo && error "'touch foo' worked after removing parent"
4942         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4943         touch .foo && error "'touch .foo' worked after removing parent"
4944         mkdir .foo && error "mkdir .foo worked after removing parent"
4945         $TRACE ls . && error "'ls .' worked after removing parent"
4946         $TRACE ls .. && error "'ls ..' worked after removing parent"
4947         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4948         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4949         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4950         true
4951 }
4952 run_test 48d "Access removed parent subdir (should return errors)"
4953
4954 test_48e() { # bug 4134
4955         #lctl set_param debug=-1
4956         #set -vx
4957         rm -rf $DIR/$tdir
4958         test_mkdir -p $DIR/$tdir/dir
4959         cd $DIR/$tdir/dir
4960         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4961         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4962         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4963         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4964         # On a buggy kernel addition of "touch foo" after cd .. will
4965         # produce kernel oops in lookup_hash_it
4966         touch ../foo && error "'cd ..' worked after recreate parent"
4967         cd $DIR
4968         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4969 }
4970 run_test 48e "Access to recreated parent subdir (should return errors)"
4971
4972 test_49() { # LU-1030
4973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4974         remote_ost_nodsh && skip "remote OST with nodsh"
4975
4976         # get ost1 size - lustre-OST0000
4977         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4978                 awk '{ print $4 }')
4979         # write 800M at maximum
4980         [[ $ost1_size -lt 2 ]] && ost1_size=2
4981         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4982
4983         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4984         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4985         local dd_pid=$!
4986
4987         # change max_pages_per_rpc while writing the file
4988         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4989         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4990         # loop until dd process exits
4991         while ps ax -opid | grep -wq $dd_pid; do
4992                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4993                 sleep $((RANDOM % 5 + 1))
4994         done
4995         # restore original max_pages_per_rpc
4996         $LCTL set_param $osc1_mppc=$orig_mppc
4997         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4998 }
4999 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5000
5001 test_50() {
5002         # bug 1485
5003         test_mkdir $DIR/$tdir
5004         cd $DIR/$tdir
5005         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5006 }
5007 run_test 50 "special situations: /proc symlinks  ==============="
5008
5009 test_51a() {    # was test_51
5010         # bug 1516 - create an empty entry right after ".." then split dir
5011         test_mkdir -c1 $DIR/$tdir
5012         touch $DIR/$tdir/foo
5013         $MCREATE $DIR/$tdir/bar
5014         rm $DIR/$tdir/foo
5015         createmany -m $DIR/$tdir/longfile 201
5016         FNUM=202
5017         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5018                 $MCREATE $DIR/$tdir/longfile$FNUM
5019                 FNUM=$(($FNUM + 1))
5020                 echo -n "+"
5021         done
5022         echo
5023         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5024 }
5025 run_test 51a "special situations: split htree with empty entry =="
5026
5027 cleanup_print_lfs_df () {
5028         trap 0
5029         $LFS df
5030         $LFS df -i
5031 }
5032
5033 test_51b() {
5034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5035
5036         local dir=$DIR/$tdir
5037         local nrdirs=$((65536 + 100))
5038
5039         # cleanup the directory
5040         rm -fr $dir
5041
5042         test_mkdir -c1 $dir
5043
5044         $LFS df
5045         $LFS df -i
5046         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5047         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5048         [[ $numfree -lt $nrdirs ]] &&
5049                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5050
5051         # need to check free space for the directories as well
5052         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5053         numfree=$(( blkfree / $(fs_inode_ksize) ))
5054         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5055
5056         trap cleanup_print_lfs_df EXIT
5057
5058         # create files
5059         createmany -d $dir/d $nrdirs || {
5060                 unlinkmany $dir/d $nrdirs
5061                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5062         }
5063
5064         # really created :
5065         nrdirs=$(ls -U $dir | wc -l)
5066
5067         # unlink all but 100 subdirectories, then check it still works
5068         local left=100
5069         local delete=$((nrdirs - left))
5070
5071         $LFS df
5072         $LFS df -i
5073
5074         # for ldiskfs the nlink count should be 1, but this is OSD specific
5075         # and so this is listed for informational purposes only
5076         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5077         unlinkmany -d $dir/d $delete ||
5078                 error "unlink of first $delete subdirs failed"
5079
5080         echo "nlink between: $(stat -c %h $dir)"
5081         local found=$(ls -U $dir | wc -l)
5082         [ $found -ne $left ] &&
5083                 error "can't find subdirs: found only $found, expected $left"
5084
5085         unlinkmany -d $dir/d $delete $left ||
5086                 error "unlink of second $left subdirs failed"
5087         # regardless of whether the backing filesystem tracks nlink accurately
5088         # or not, the nlink count shouldn't be more than "." and ".." here
5089         local after=$(stat -c %h $dir)
5090         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5091                 echo "nlink after: $after"
5092
5093         cleanup_print_lfs_df
5094 }
5095 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5096
5097 test_51d() {
5098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5099         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5100
5101         test_mkdir $DIR/$tdir
5102         createmany -o $DIR/$tdir/t- 1000
5103         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5104         for N in $(seq 0 $((OSTCOUNT - 1))); do
5105                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5106                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5107                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5108                         '($1 == '$N') { objs += 1 } \
5109                         END { printf("%0.0f", objs) }')
5110                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5111         done
5112         unlinkmany $DIR/$tdir/t- 1000
5113
5114         NLAST=0
5115         for N in $(seq 1 $((OSTCOUNT - 1))); do
5116                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5117                         error "OST $N has less objects vs OST $NLAST" \
5118                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5119                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5120                         error "OST $N has less objects vs OST $NLAST" \
5121                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5122
5123                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5124                         error "OST $N has less #0 objects vs OST $NLAST" \
5125                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5126                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5127                         error "OST $N has less #0 objects vs OST $NLAST" \
5128                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5129                 NLAST=$N
5130         done
5131         rm -f $TMP/$tfile
5132 }
5133 run_test 51d "check object distribution"
5134
5135 test_51e() {
5136         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5137                 skip_env "ldiskfs only test"
5138         fi
5139
5140         test_mkdir -c1 $DIR/$tdir
5141         test_mkdir -c1 $DIR/$tdir/d0
5142
5143         touch $DIR/$tdir/d0/foo
5144         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5145                 error "file exceed 65000 nlink limit!"
5146         unlinkmany $DIR/$tdir/d0/f- 65001
5147         return 0
5148 }
5149 run_test 51e "check file nlink limit"
5150
5151 test_51f() {
5152         test_mkdir $DIR/$tdir
5153
5154         local max=100000
5155         local ulimit_old=$(ulimit -n)
5156         local spare=20 # number of spare fd's for scripts/libraries, etc.
5157         local mdt=$($LFS getstripe -m $DIR/$tdir)
5158         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5159
5160         echo "MDT$mdt numfree=$numfree, max=$max"
5161         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5162         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5163                 while ! ulimit -n $((numfree + spare)); do
5164                         numfree=$((numfree * 3 / 4))
5165                 done
5166                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5167         else
5168                 echo "left ulimit at $ulimit_old"
5169         fi
5170
5171         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5172                 unlinkmany $DIR/$tdir/f $numfree
5173                 error "create+open $numfree files in $DIR/$tdir failed"
5174         }
5175         ulimit -n $ulimit_old
5176
5177         # if createmany exits at 120s there will be fewer than $numfree files
5178         unlinkmany $DIR/$tdir/f $numfree || true
5179 }
5180 run_test 51f "check many open files limit"
5181
5182 test_52a() {
5183         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5184         test_mkdir $DIR/$tdir
5185         touch $DIR/$tdir/foo
5186         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5187         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5188         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5189         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5190         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5191                                         error "link worked"
5192         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5193         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5194         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5195                                                      error "lsattr"
5196         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5197         cp -r $DIR/$tdir $TMP/
5198         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5199 }
5200 run_test 52a "append-only flag test (should return errors)"
5201
5202 test_52b() {
5203         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5204         test_mkdir $DIR/$tdir
5205         touch $DIR/$tdir/foo
5206         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5207         cat test > $DIR/$tdir/foo && error "cat test worked"
5208         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5209         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5210         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5211                                         error "link worked"
5212         echo foo >> $DIR/$tdir/foo && error "echo worked"
5213         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5214         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5215         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5216         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5217                                                         error "lsattr"
5218         chattr -i $DIR/$tdir/foo || error "chattr failed"
5219
5220         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5221 }
5222 run_test 52b "immutable flag test (should return errors) ======="
5223
5224 test_53() {
5225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5226         remote_mds_nodsh && skip "remote MDS with nodsh"
5227         remote_ost_nodsh && skip "remote OST with nodsh"
5228
5229         local param
5230         local param_seq
5231         local ostname
5232         local mds_last
5233         local mds_last_seq
5234         local ost_last
5235         local ost_last_seq
5236         local ost_last_id
5237         local ostnum
5238         local node
5239         local found=false
5240         local support_last_seq=true
5241
5242         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5243                 support_last_seq=false
5244
5245         # only test MDT0000
5246         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5247         local value
5248         for value in $(do_facet $SINGLEMDS \
5249                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5250                 param=$(echo ${value[0]} | cut -d "=" -f1)
5251                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5252
5253                 if $support_last_seq; then
5254                         param_seq=$(echo $param |
5255                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5256                         mds_last_seq=$(do_facet $SINGLEMDS \
5257                                        $LCTL get_param -n $param_seq)
5258                 fi
5259                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5260
5261                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5262                 node=$(facet_active_host ost$((ostnum+1)))
5263                 param="obdfilter.$ostname.last_id"
5264                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5265                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5266                         ost_last_id=$ost_last
5267
5268                         if $support_last_seq; then
5269                                 ost_last_id=$(echo $ost_last |
5270                                               awk -F':' '{print $2}' |
5271                                               sed -e "s/^0x//g")
5272                                 ost_last_seq=$(echo $ost_last |
5273                                                awk -F':' '{print $1}')
5274                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5275                         fi
5276
5277                         if [[ $ost_last_id != $mds_last ]]; then
5278                                 error "$ost_last_id != $mds_last"
5279                         else
5280                                 found=true
5281                                 break
5282                         fi
5283                 done
5284         done
5285         $found || error "can not match last_seq/last_id for $mdtosc"
5286         return 0
5287 }
5288 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5289
5290 test_54a() {
5291         perl -MSocket -e ';' || skip "no Socket perl module installed"
5292
5293         $SOCKETSERVER $DIR/socket ||
5294                 error "$SOCKETSERVER $DIR/socket failed: $?"
5295         $SOCKETCLIENT $DIR/socket ||
5296                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5297         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5298 }
5299 run_test 54a "unix domain socket test =========================="
5300
5301 test_54b() {
5302         f="$DIR/f54b"
5303         mknod $f c 1 3
5304         chmod 0666 $f
5305         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5306 }
5307 run_test 54b "char device works in lustre ======================"
5308
5309 find_loop_dev() {
5310         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5311         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5312         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5313
5314         for i in $(seq 3 7); do
5315                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5316                 LOOPDEV=$LOOPBASE$i
5317                 LOOPNUM=$i
5318                 break
5319         done
5320 }
5321
5322 cleanup_54c() {
5323         local rc=0
5324         loopdev="$DIR/loop54c"
5325
5326         trap 0
5327         $UMOUNT $DIR/$tdir || rc=$?
5328         losetup -d $loopdev || true
5329         losetup -d $LOOPDEV || true
5330         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5331         return $rc
5332 }
5333
5334 test_54c() {
5335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5336
5337         loopdev="$DIR/loop54c"
5338
5339         find_loop_dev
5340         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5341         trap cleanup_54c EXIT
5342         mknod $loopdev b 7 $LOOPNUM
5343         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5344         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5345         losetup $loopdev $DIR/$tfile ||
5346                 error "can't set up $loopdev for $DIR/$tfile"
5347         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5348         test_mkdir $DIR/$tdir
5349         mount -t ext2 $loopdev $DIR/$tdir ||
5350                 error "error mounting $loopdev on $DIR/$tdir"
5351         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5352                 error "dd write"
5353         df $DIR/$tdir
5354         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5355                 error "dd read"
5356         cleanup_54c
5357 }
5358 run_test 54c "block device works in lustre ====================="
5359
5360 test_54d() {
5361         f="$DIR/f54d"
5362         string="aaaaaa"
5363         mknod $f p
5364         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5365 }
5366 run_test 54d "fifo device works in lustre ======================"
5367
5368 test_54e() {
5369         f="$DIR/f54e"
5370         string="aaaaaa"
5371         cp -aL /dev/console $f
5372         echo $string > $f || error "echo $string to $f failed"
5373 }
5374 run_test 54e "console/tty device works in lustre ======================"
5375
5376 test_56a() {
5377         local numfiles=3
5378         local dir=$DIR/$tdir
5379
5380         rm -rf $dir
5381         test_mkdir -p $dir/dir
5382         for i in $(seq $numfiles); do
5383                 touch $dir/file$i
5384                 touch $dir/dir/file$i
5385         done
5386
5387         local numcomp=$($LFS getstripe --component-count $dir)
5388
5389         [[ $numcomp == 0 ]] && numcomp=1
5390
5391         # test lfs getstripe with --recursive
5392         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5393
5394         [[ $filenum -eq $((numfiles * 2)) ]] ||
5395                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5396         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5397         [[ $filenum -eq $numfiles ]] ||
5398                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5399         echo "$LFS getstripe showed obdidx or l_ost_idx"
5400
5401         # test lfs getstripe with file instead of dir
5402         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5403         [[ $filenum -eq 1 ]] ||
5404                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5405         echo "$LFS getstripe file1 passed"
5406
5407         #test lfs getstripe with --verbose
5408         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5409         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5410                 error "$LFS getstripe --verbose $dir: "\
5411                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5412         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5413                 error "$LFS getstripe $dir: showed lmm_magic"
5414
5415         #test lfs getstripe with -v prints lmm_fid
5416         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5417         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5418                 error "$LFS getstripe -v $dir: "\
5419                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5420         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5421                 error "$LFS getstripe $dir: showed lmm_fid by default"
5422         echo "$LFS getstripe --verbose passed"
5423
5424         #check for FID information
5425         local fid1=$($LFS getstripe --fid $dir/file1)
5426         local fid2=$($LFS getstripe --verbose $dir/file1 |
5427                      awk '/lmm_fid: / { print $2; exit; }')
5428         local fid3=$($LFS path2fid $dir/file1)
5429
5430         [ "$fid1" != "$fid2" ] &&
5431                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5432         [ "$fid1" != "$fid3" ] &&
5433                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5434         echo "$LFS getstripe --fid passed"
5435
5436         #test lfs getstripe with --obd
5437         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5438                 error "$LFS getstripe --obd wrong_uuid: should return error"
5439
5440         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5441
5442         local ostidx=1
5443         local obduuid=$(ostuuid_from_index $ostidx)
5444         local found=$($LFS getstripe -r --obd $obduuid $dir |
5445                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5446
5447         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5448         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5449                 ((filenum--))
5450         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5451                 ((filenum--))
5452
5453         [[ $found -eq $filenum ]] ||
5454                 error "$LFS getstripe --obd: found $found expect $filenum"
5455         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5456                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5457                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5458                 error "$LFS getstripe --obd: should not show file on other obd"
5459         echo "$LFS getstripe --obd passed"
5460 }
5461 run_test 56a "check $LFS getstripe"
5462
5463 test_56b() {
5464         local dir=$DIR/$tdir
5465         local numdirs=3
5466
5467         test_mkdir $dir
5468         for i in $(seq $numdirs); do
5469                 test_mkdir $dir/dir$i
5470         done
5471
5472         # test lfs getdirstripe default mode is non-recursion, which is
5473         # different from lfs getstripe
5474         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5475
5476         [[ $dircnt -eq 1 ]] ||
5477                 error "$LFS getdirstripe: found $dircnt, not 1"
5478         dircnt=$($LFS getdirstripe --recursive $dir |
5479                 grep -c lmv_stripe_count)
5480         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5481                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5482 }
5483 run_test 56b "check $LFS getdirstripe"
5484
5485 test_56c() {
5486         remote_ost_nodsh && skip "remote OST with nodsh"
5487
5488         local ost_idx=0
5489         local ost_name=$(ostname_from_index $ost_idx)
5490         local old_status=$(ost_dev_status $ost_idx)
5491
5492         [[ -z "$old_status" ]] ||
5493                 skip_env "OST $ost_name is in $old_status status"
5494
5495         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5496         sleep_maxage
5497
5498         local new_status=$(ost_dev_status $ost_idx)
5499
5500         [[ "$new_status" = "D" ]] ||
5501                 error "OST $ost_name is in status of '$new_status', not 'D'"
5502
5503         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5504         sleep_maxage
5505
5506         new_status=$(ost_dev_status $ost_idx)
5507         [[ -z "$new_status" ]] ||
5508                 error "OST $ost_name is in status of '$new_status', not ''"
5509 }
5510 run_test 56c "check 'lfs df' showing device status"
5511
5512 NUMFILES=3
5513 NUMDIRS=3
5514 setup_56() {
5515         local local_tdir="$1"
5516         local local_numfiles="$2"
5517         local local_numdirs="$3"
5518         local dir_params="$4"
5519         local dir_stripe_params="$5"
5520
5521         if [ ! -d "$local_tdir" ] ; then
5522                 test_mkdir -p $dir_stripe_params $local_tdir
5523                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5524                 for i in $(seq $local_numfiles) ; do
5525                         touch $local_tdir/file$i
5526                 done
5527                 for i in $(seq $local_numdirs) ; do
5528                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5529                         for j in $(seq $local_numfiles) ; do
5530                                 touch $local_tdir/dir$i/file$j
5531                         done
5532                 done
5533         fi
5534 }
5535
5536 setup_56_special() {
5537         local local_tdir=$1
5538         local local_numfiles=$2
5539         local local_numdirs=$3
5540
5541         setup_56 $local_tdir $local_numfiles $local_numdirs
5542
5543         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5544                 for i in $(seq $local_numfiles) ; do
5545                         mknod $local_tdir/loop${i}b b 7 $i
5546                         mknod $local_tdir/null${i}c c 1 3
5547                         ln -s $local_tdir/file1 $local_tdir/link${i}
5548                 done
5549                 for i in $(seq $local_numdirs) ; do
5550                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5551                         mknod $local_tdir/dir$i/null${i}c c 1 3
5552                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5553                 done
5554         fi
5555 }
5556
5557 test_56g() {
5558         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5559         local expected=$(($NUMDIRS + 2))
5560
5561         setup_56 $dir $NUMFILES $NUMDIRS
5562
5563         # test lfs find with -name
5564         for i in $(seq $NUMFILES) ; do
5565                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5566
5567                 [ $nums -eq $expected ] ||
5568                         error "lfs find -name '*$i' $dir wrong: "\
5569                               "found $nums, expected $expected"
5570         done
5571 }
5572 run_test 56g "check lfs find -name"
5573
5574 test_56h() {
5575         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5576         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5577
5578         setup_56 $dir $NUMFILES $NUMDIRS
5579
5580         # test lfs find with ! -name
5581         for i in $(seq $NUMFILES) ; do
5582                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5583
5584                 [ $nums -eq $expected ] ||
5585                         error "lfs find ! -name '*$i' $dir wrong: "\
5586                               "found $nums, expected $expected"
5587         done
5588 }
5589 run_test 56h "check lfs find ! -name"
5590
5591 test_56i() {
5592         local dir=$DIR/$tdir
5593
5594         test_mkdir $dir
5595
5596         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5597         local out=$($cmd)
5598
5599         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5600 }
5601 run_test 56i "check 'lfs find -ost UUID' skips directories"
5602
5603 test_56j() {
5604         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5605
5606         setup_56_special $dir $NUMFILES $NUMDIRS
5607
5608         local expected=$((NUMDIRS + 1))
5609         local cmd="$LFS find -type d $dir"
5610         local nums=$($cmd | wc -l)
5611
5612         [ $nums -eq $expected ] ||
5613                 error "'$cmd' wrong: found $nums, expected $expected"
5614 }
5615 run_test 56j "check lfs find -type d"
5616
5617 test_56k() {
5618         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5619
5620         setup_56_special $dir $NUMFILES $NUMDIRS
5621
5622         local expected=$(((NUMDIRS + 1) * NUMFILES))
5623         local cmd="$LFS find -type f $dir"
5624         local nums=$($cmd | wc -l)
5625
5626         [ $nums -eq $expected ] ||
5627                 error "'$cmd' wrong: found $nums, expected $expected"
5628 }
5629 run_test 56k "check lfs find -type f"
5630
5631 test_56l() {
5632         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5633
5634         setup_56_special $dir $NUMFILES $NUMDIRS
5635
5636         local expected=$((NUMDIRS + NUMFILES))
5637         local cmd="$LFS find -type b $dir"
5638         local nums=$($cmd | wc -l)
5639
5640         [ $nums -eq $expected ] ||
5641                 error "'$cmd' wrong: found $nums, expected $expected"
5642 }
5643 run_test 56l "check lfs find -type b"
5644
5645 test_56m() {
5646         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5647
5648         setup_56_special $dir $NUMFILES $NUMDIRS
5649
5650         local expected=$((NUMDIRS + NUMFILES))
5651         local cmd="$LFS find -type c $dir"
5652         local nums=$($cmd | wc -l)
5653         [ $nums -eq $expected ] ||
5654                 error "'$cmd' wrong: found $nums, expected $expected"
5655 }
5656 run_test 56m "check lfs find -type c"
5657
5658 test_56n() {
5659         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5660         setup_56_special $dir $NUMFILES $NUMDIRS
5661
5662         local expected=$((NUMDIRS + NUMFILES))
5663         local cmd="$LFS find -type l $dir"
5664         local nums=$($cmd | wc -l)
5665
5666         [ $nums -eq $expected ] ||
5667                 error "'$cmd' wrong: found $nums, expected $expected"
5668 }
5669 run_test 56n "check lfs find -type l"
5670
5671 test_56o() {
5672         local dir=$DIR/$tdir
5673
5674         setup_56 $dir $NUMFILES $NUMDIRS
5675         utime $dir/file1 > /dev/null || error "utime (1)"
5676         utime $dir/file2 > /dev/null || error "utime (2)"
5677         utime $dir/dir1 > /dev/null || error "utime (3)"
5678         utime $dir/dir2 > /dev/null || error "utime (4)"
5679         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5680         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5681
5682         local expected=4
5683         local nums=$($LFS find -mtime +0 $dir | wc -l)
5684
5685         [ $nums -eq $expected ] ||
5686                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5687
5688         expected=12
5689         cmd="$LFS find -mtime 0 $dir"
5690         nums=$($cmd | wc -l)
5691         [ $nums -eq $expected ] ||
5692                 error "'$cmd' wrong: found $nums, expected $expected"
5693 }
5694 run_test 56o "check lfs find -mtime for old files"
5695
5696 test_56ob() {
5697         local dir=$DIR/$tdir
5698         local expected=1
5699         local count=0
5700
5701         # just to make sure there is something that won't be found
5702         test_mkdir $dir
5703         touch $dir/$tfile.now
5704
5705         for age in year week day hour min; do
5706                 count=$((count + 1))
5707
5708                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5709                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5710                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5711
5712                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5713                 local nums=$($cmd | wc -l)
5714                 [ $nums -eq $expected ] ||
5715                         error "'$cmd' wrong: found $nums, expected $expected"
5716
5717                 cmd="$LFS find $dir -atime $count${age:0:1}"
5718                 nums=$($cmd | wc -l)
5719                 [ $nums -eq $expected ] ||
5720                         error "'$cmd' wrong: found $nums, expected $expected"
5721         done
5722
5723         sleep 2
5724         cmd="$LFS find $dir -ctime +1s -type f"
5725         nums=$($cmd | wc -l)
5726         (( $nums == $count * 2 + 1)) ||
5727                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5728 }
5729 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5730
5731 test_56p() {
5732         [ $RUNAS_ID -eq $UID ] &&
5733                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5734
5735         local dir=$DIR/$tdir
5736
5737         setup_56 $dir $NUMFILES $NUMDIRS
5738         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5739
5740         local expected=$NUMFILES
5741         local cmd="$LFS find -uid $RUNAS_ID $dir"
5742         local nums=$($cmd | wc -l)
5743
5744         [ $nums -eq $expected ] ||
5745                 error "'$cmd' wrong: found $nums, expected $expected"
5746
5747         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5748         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5749         nums=$($cmd | wc -l)
5750         [ $nums -eq $expected ] ||
5751                 error "'$cmd' wrong: found $nums, expected $expected"
5752 }
5753 run_test 56p "check lfs find -uid and ! -uid"
5754
5755 test_56q() {
5756         [ $RUNAS_ID -eq $UID ] &&
5757                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5758
5759         local dir=$DIR/$tdir
5760
5761         setup_56 $dir $NUMFILES $NUMDIRS
5762         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5763
5764         local expected=$NUMFILES
5765         local cmd="$LFS find -gid $RUNAS_GID $dir"
5766         local nums=$($cmd | wc -l)
5767
5768         [ $nums -eq $expected ] ||
5769                 error "'$cmd' wrong: found $nums, expected $expected"
5770
5771         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5772         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5773         nums=$($cmd | wc -l)
5774         [ $nums -eq $expected ] ||
5775                 error "'$cmd' wrong: found $nums, expected $expected"
5776 }
5777 run_test 56q "check lfs find -gid and ! -gid"
5778
5779 test_56r() {
5780         local dir=$DIR/$tdir
5781
5782         setup_56 $dir $NUMFILES $NUMDIRS
5783
5784         local expected=12
5785         local cmd="$LFS find -size 0 -type f -lazy $dir"
5786         local nums=$($cmd | wc -l)
5787
5788         [ $nums -eq $expected ] ||
5789                 error "'$cmd' wrong: found $nums, expected $expected"
5790         cmd="$LFS find -size 0 -type f $dir"
5791         nums=$($cmd | wc -l)
5792         [ $nums -eq $expected ] ||
5793                 error "'$cmd' wrong: found $nums, expected $expected"
5794
5795         expected=0
5796         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5797         nums=$($cmd | wc -l)
5798         [ $nums -eq $expected ] ||
5799                 error "'$cmd' wrong: found $nums, expected $expected"
5800         cmd="$LFS find ! -size 0 -type f $dir"
5801         nums=$($cmd | wc -l)
5802         [ $nums -eq $expected ] ||
5803                 error "'$cmd' wrong: found $nums, expected $expected"
5804
5805         echo "test" > $dir/$tfile
5806         echo "test2" > $dir/$tfile.2 && sync
5807         expected=1
5808         cmd="$LFS find -size 5 -type f -lazy $dir"
5809         nums=$($cmd | wc -l)
5810         [ $nums -eq $expected ] ||
5811                 error "'$cmd' wrong: found $nums, expected $expected"
5812         cmd="$LFS find -size 5 -type f $dir"
5813         nums=$($cmd | wc -l)
5814         [ $nums -eq $expected ] ||
5815                 error "'$cmd' wrong: found $nums, expected $expected"
5816
5817         expected=1
5818         cmd="$LFS find -size +5 -type f -lazy $dir"
5819         nums=$($cmd | wc -l)
5820         [ $nums -eq $expected ] ||
5821                 error "'$cmd' wrong: found $nums, expected $expected"
5822         cmd="$LFS find -size +5 -type f $dir"
5823         nums=$($cmd | wc -l)
5824         [ $nums -eq $expected ] ||
5825                 error "'$cmd' wrong: found $nums, expected $expected"
5826
5827         expected=2
5828         cmd="$LFS find -size +0 -type f -lazy $dir"
5829         nums=$($cmd | wc -l)
5830         [ $nums -eq $expected ] ||
5831                 error "'$cmd' wrong: found $nums, expected $expected"
5832         cmd="$LFS find -size +0 -type f $dir"
5833         nums=$($cmd | wc -l)
5834         [ $nums -eq $expected ] ||
5835                 error "'$cmd' wrong: found $nums, expected $expected"
5836
5837         expected=2
5838         cmd="$LFS find ! -size -5 -type f -lazy $dir"
5839         nums=$($cmd | wc -l)
5840         [ $nums -eq $expected ] ||
5841                 error "'$cmd' wrong: found $nums, expected $expected"
5842         cmd="$LFS find ! -size -5 -type f $dir"
5843         nums=$($cmd | wc -l)
5844         [ $nums -eq $expected ] ||
5845                 error "'$cmd' wrong: found $nums, expected $expected"
5846
5847         expected=12
5848         cmd="$LFS find -size -5 -type f -lazy $dir"
5849         nums=$($cmd | wc -l)
5850         [ $nums -eq $expected ] ||
5851                 error "'$cmd' wrong: found $nums, expected $expected"
5852         cmd="$LFS find -size -5 -type f $dir"
5853         nums=$($cmd | wc -l)
5854         [ $nums -eq $expected ] ||
5855                 error "'$cmd' wrong: found $nums, expected $expected"
5856 }
5857 run_test 56r "check lfs find -size works"
5858
5859 test_56ra() {
5860         local dir=$DIR/$tdir
5861
5862         [[ $OSC == "mdc" ]] && skip "DoM files" && return
5863
5864         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5865
5866         cancel_lru_locks $OSC
5867
5868         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5869         local expected=12
5870         local cmd="$LFS find -size 0 -type f -lazy $dir"
5871         local nums=$($cmd | wc -l)
5872
5873         [ $nums -eq $expected ] ||
5874                 error "'$cmd' wrong: found $nums, expected $expected"
5875
5876         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5877         [ $rpcs_before -eq $rpcs_after ] ||
5878                 error "'$cmd' should not send glimpse RPCs to OST"
5879         cmd="$LFS find -size 0 -type f $dir"
5880         nums=$($cmd | wc -l)
5881         [ $nums -eq $expected ] ||
5882                 error "'$cmd' wrong: found $nums, expected $expected"
5883         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5884         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5885         $LCTL get_param osc.*.stats
5886         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
5887                 error "'$cmd' should send 12 glimpse RPCs to OST"
5888
5889         cancel_lru_locks $OSC
5890         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5891         expected=0
5892         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5893         nums=$($cmd | wc -l)
5894         [ $nums -eq $expected ] ||
5895                 error "'$cmd' wrong: found $nums, expected $expected"
5896         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5897         $LCTL get_param mdc.*.stats
5898         [ $rpcs_before -eq $rpcs_after ] ||
5899                 error "'$cmd' should not send glimpse RPCs to OST"
5900         cmd="$LFS find ! -size 0 -type f $dir"
5901         nums=$($cmd | wc -l)
5902         [ $nums -eq $expected ] ||
5903                 error "'$cmd' wrong: found $nums, expected $expected"
5904         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5905         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5906         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
5907                 error "'$cmd' should send 12 glimpse RPCs to OST"
5908
5909         echo "test" > $dir/$tfile
5910         echo "test2" > $dir/$tfile.2 && sync
5911         cancel_lru_locks $OSC
5912         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5913         expected=1
5914         cmd="$LFS find -size 5 -type f -lazy $dir"
5915         nums=$($cmd | wc -l)
5916         [ $nums -eq $expected ] ||
5917                 error "'$cmd' wrong: found $nums, expected $expected"
5918         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5919         [ $rpcs_before -eq $rpcs_after ] ||
5920                 error "'$cmd' should not send glimpse RPCs to OST"
5921         cmd="$LFS find -size 5 -type f $dir"
5922         nums=$($cmd | wc -l)
5923         [ $nums -eq $expected ] ||
5924                 error "'$cmd' wrong: found $nums, expected $expected"
5925         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5926         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5927         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5928                 error "'$cmd' should send 14 glimpse RPCs to OST"
5929
5930         cancel_lru_locks $OSC
5931         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5932         expected=1
5933         cmd="$LFS find -size +5 -type f -lazy $dir"
5934         nums=$($cmd | wc -l)
5935         [ $nums -eq $expected ] ||
5936                 error "'$cmd' wrong: found $nums, expected $expected"
5937         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5938         [ $rpcs_before -eq $rpcs_after ] ||
5939                 error "'$cmd' should not send glimpse RPCs to OST"
5940         cmd="$LFS find -size +5 -type f $dir"
5941         nums=$($cmd | wc -l)
5942         [ $nums -eq $expected ] ||
5943                 error "'$cmd' wrong: found $nums, expected $expected"
5944         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5945         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5946         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5947                 error "'$cmd' should send 14 glimpse RPCs to OST"
5948
5949         cancel_lru_locks $OSC
5950         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5951         expected=2
5952         cmd="$LFS find -size +0 -type f -lazy $dir"
5953         nums=$($cmd | wc -l)
5954         [ $nums -eq $expected ] ||
5955                 error "'$cmd' wrong: found $nums, expected $expected"
5956         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5957         [ $rpcs_before -eq $rpcs_after ] ||
5958                 error "'$cmd' should not send glimpse RPCs to OST"
5959         cmd="$LFS find -size +0 -type f $dir"
5960         nums=$($cmd | wc -l)
5961         [ $nums -eq $expected ] ||
5962                 error "'$cmd' wrong: found $nums, expected $expected"
5963         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5964         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5965         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5966                 error "'$cmd' should send 14 glimpse RPCs to OST"
5967
5968         cancel_lru_locks $OSC
5969         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5970         expected=2
5971         cmd="$LFS find ! -size -5 -type f -lazy $dir"
5972         nums=$($cmd | wc -l)
5973         [ $nums -eq $expected ] ||
5974                 error "'$cmd' wrong: found $nums, expected $expected"
5975         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5976         [ $rpcs_before -eq $rpcs_after ] ||
5977                 error "'$cmd' should not send glimpse RPCs to OST"
5978         cmd="$LFS find ! -size -5 -type f $dir"
5979         nums=$($cmd | wc -l)
5980         [ $nums -eq $expected ] ||
5981                 error "'$cmd' wrong: found $nums, expected $expected"
5982         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5983         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5984         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5985                 error "'$cmd' should send 14 glimpse RPCs to OST"
5986
5987         cancel_lru_locks $OSC
5988         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5989         expected=12
5990         cmd="$LFS find -size -5 -type f -lazy $dir"
5991         nums=$($cmd | wc -l)
5992         [ $nums -eq $expected ] ||
5993                 error "'$cmd' wrong: found $nums, expected $expected"
5994         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5995         [ $rpcs_before -eq $rpcs_after ] ||
5996                 error "'$cmd' should not send glimpse RPCs to OST"
5997         cmd="$LFS find -size -5 -type f $dir"
5998         nums=$($cmd | wc -l)
5999         [ $nums -eq $expected ] ||
6000                 error "'$cmd' wrong: found $nums, expected $expected"
6001         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6002         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6003         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6004                 error "'$cmd' should send 14 glimpse RPCs to OST"
6005 }
6006 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6007
6008 test_56s() { # LU-611 #LU-9369
6009         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6010
6011         local dir=$DIR/$tdir
6012         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6013
6014         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6015         for i in $(seq $NUMDIRS); do
6016                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6017         done
6018
6019         local expected=$NUMDIRS
6020         local cmd="$LFS find -c $OSTCOUNT $dir"
6021         local nums=$($cmd | wc -l)
6022
6023         [ $nums -eq $expected ] || {
6024                 $LFS getstripe -R $dir
6025                 error "'$cmd' wrong: found $nums, expected $expected"
6026         }
6027
6028         expected=$((NUMDIRS + onestripe))
6029         cmd="$LFS find -stripe-count +0 -type f $dir"
6030         nums=$($cmd | wc -l)
6031         [ $nums -eq $expected ] || {
6032                 $LFS getstripe -R $dir
6033                 error "'$cmd' wrong: found $nums, expected $expected"
6034         }
6035
6036         expected=$onestripe
6037         cmd="$LFS find -stripe-count 1 -type f $dir"
6038         nums=$($cmd | wc -l)
6039         [ $nums -eq $expected ] || {
6040                 $LFS getstripe -R $dir
6041                 error "'$cmd' wrong: found $nums, expected $expected"
6042         }
6043
6044         cmd="$LFS find -stripe-count -2 -type f $dir"
6045         nums=$($cmd | wc -l)
6046         [ $nums -eq $expected ] || {
6047                 $LFS getstripe -R $dir
6048                 error "'$cmd' wrong: found $nums, expected $expected"
6049         }
6050
6051         expected=0
6052         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6053         nums=$($cmd | wc -l)
6054         [ $nums -eq $expected ] || {
6055                 $LFS getstripe -R $dir
6056                 error "'$cmd' wrong: found $nums, expected $expected"
6057         }
6058 }
6059 run_test 56s "check lfs find -stripe-count works"
6060
6061 test_56t() { # LU-611 #LU-9369
6062         local dir=$DIR/$tdir
6063
6064         setup_56 $dir 0 $NUMDIRS
6065         for i in $(seq $NUMDIRS); do
6066                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6067         done
6068
6069         local expected=$NUMDIRS
6070         local cmd="$LFS find -S 8M $dir"
6071         local nums=$($cmd | wc -l)
6072
6073         [ $nums -eq $expected ] || {
6074                 $LFS getstripe -R $dir
6075                 error "'$cmd' wrong: found $nums, expected $expected"
6076         }
6077         rm -rf $dir
6078
6079         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6080
6081         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6082
6083         expected=$(((NUMDIRS + 1) * NUMFILES))
6084         cmd="$LFS find -stripe-size 512k -type f $dir"
6085         nums=$($cmd | wc -l)
6086         [ $nums -eq $expected ] ||
6087                 error "'$cmd' wrong: found $nums, expected $expected"
6088
6089         cmd="$LFS find -stripe-size +320k -type f $dir"
6090         nums=$($cmd | wc -l)
6091         [ $nums -eq $expected ] ||
6092                 error "'$cmd' wrong: found $nums, expected $expected"
6093
6094         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6095         cmd="$LFS find -stripe-size +200k -type f $dir"
6096         nums=$($cmd | wc -l)
6097         [ $nums -eq $expected ] ||
6098                 error "'$cmd' wrong: found $nums, expected $expected"
6099
6100         cmd="$LFS find -stripe-size -640k -type f $dir"
6101         nums=$($cmd | wc -l)
6102         [ $nums -eq $expected ] ||
6103                 error "'$cmd' wrong: found $nums, expected $expected"
6104
6105         expected=4
6106         cmd="$LFS find -stripe-size 256k -type f $dir"
6107         nums=$($cmd | wc -l)
6108         [ $nums -eq $expected ] ||
6109                 error "'$cmd' wrong: found $nums, expected $expected"
6110
6111         cmd="$LFS find -stripe-size -320k -type f $dir"
6112         nums=$($cmd | wc -l)
6113         [ $nums -eq $expected ] ||
6114                 error "'$cmd' wrong: found $nums, expected $expected"
6115
6116         expected=0
6117         cmd="$LFS find -stripe-size 1024k -type f $dir"
6118         nums=$($cmd | wc -l)
6119         [ $nums -eq $expected ] ||
6120                 error "'$cmd' wrong: found $nums, expected $expected"
6121 }
6122 run_test 56t "check lfs find -stripe-size works"
6123
6124 test_56u() { # LU-611
6125         local dir=$DIR/$tdir
6126
6127         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6128
6129         if [[ $OSTCOUNT -gt 1 ]]; then
6130                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6131                 onestripe=4
6132         else
6133                 onestripe=0
6134         fi
6135
6136         local expected=$(((NUMDIRS + 1) * NUMFILES))
6137         local cmd="$LFS find -stripe-index 0 -type f $dir"
6138         local nums=$($cmd | wc -l)
6139
6140         [ $nums -eq $expected ] ||
6141                 error "'$cmd' wrong: found $nums, expected $expected"
6142
6143         expected=$onestripe
6144         cmd="$LFS find -stripe-index 1 -type f $dir"
6145         nums=$($cmd | wc -l)
6146         [ $nums -eq $expected ] ||
6147                 error "'$cmd' wrong: found $nums, expected $expected"
6148
6149         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6150         nums=$($cmd | wc -l)
6151         [ $nums -eq $expected ] ||
6152                 error "'$cmd' wrong: found $nums, expected $expected"
6153
6154         expected=0
6155         # This should produce an error and not return any files
6156         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6157         nums=$($cmd 2>/dev/null | wc -l)
6158         [ $nums -eq $expected ] ||
6159                 error "'$cmd' wrong: found $nums, expected $expected"
6160
6161         if [[ $OSTCOUNT -gt 1 ]]; then
6162                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6163                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6164                 nums=$($cmd | wc -l)
6165                 [ $nums -eq $expected ] ||
6166                         error "'$cmd' wrong: found $nums, expected $expected"
6167         fi
6168 }
6169 run_test 56u "check lfs find -stripe-index works"
6170
6171 test_56v() {
6172         local mdt_idx=0
6173         local dir=$DIR/$tdir
6174
6175         setup_56 $dir $NUMFILES $NUMDIRS
6176
6177         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6178         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6179
6180         for file in $($LFS find -m $UUID $dir); do
6181                 file_midx=$($LFS getstripe -m $file)
6182                 [ $file_midx -eq $mdt_idx ] ||
6183                         error "lfs find -m $UUID != getstripe -m $file_midx"
6184         done
6185 }
6186 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6187
6188 test_56w() {
6189         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6191
6192         local dir=$DIR/$tdir
6193
6194         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6195
6196         local stripe_size=$($LFS getstripe -S -d $dir) ||
6197                 error "$LFS getstripe -S -d $dir failed"
6198         stripe_size=${stripe_size%% *}
6199
6200         local file_size=$((stripe_size * OSTCOUNT))
6201         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6202         local required_space=$((file_num * file_size))
6203         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6204                            head -n1)
6205         [[ $free_space -le $((required_space / 1024)) ]] &&
6206                 skip_env "need $required_space, have $free_space kbytes"
6207
6208         local dd_bs=65536
6209         local dd_count=$((file_size / dd_bs))
6210
6211         # write data into the files
6212         local i
6213         local j
6214         local file
6215
6216         for i in $(seq $NUMFILES); do
6217                 file=$dir/file$i
6218                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6219                         error "write data into $file failed"
6220         done
6221         for i in $(seq $NUMDIRS); do
6222                 for j in $(seq $NUMFILES); do
6223                         file=$dir/dir$i/file$j
6224                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6225                                 error "write data into $file failed"
6226                 done
6227         done
6228
6229         # $LFS_MIGRATE will fail if hard link migration is unsupported
6230         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
6231                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6232                         error "creating links to $dir/dir1/file1 failed"
6233         fi
6234
6235         local expected=-1
6236
6237         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6238
6239         # lfs_migrate file
6240         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6241
6242         echo "$cmd"
6243         eval $cmd || error "$cmd failed"
6244
6245         check_stripe_count $dir/file1 $expected
6246
6247         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6248         then
6249                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6250                 # OST 1 if it is on OST 0. This file is small enough to
6251                 # be on only one stripe.
6252                 file=$dir/migr_1_ost
6253                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6254                         error "write data into $file failed"
6255                 local obdidx=$($LFS getstripe -i $file)
6256                 local oldmd5=$(md5sum $file)
6257                 local newobdidx=0
6258
6259                 [[ $obdidx -eq 0 ]] && newobdidx=1
6260                 cmd="$LFS migrate -i $newobdidx $file"
6261                 echo $cmd
6262                 eval $cmd || error "$cmd failed"
6263
6264                 local realobdix=$($LFS getstripe -i $file)
6265                 local newmd5=$(md5sum $file)
6266
6267                 [[ $newobdidx -ne $realobdix ]] &&
6268                         error "new OST is different (was=$obdidx, "\
6269                               "wanted=$newobdidx, got=$realobdix)"
6270                 [[ "$oldmd5" != "$newmd5" ]] &&
6271                         error "md5sum differ: $oldmd5, $newmd5"
6272         fi
6273
6274         # lfs_migrate dir
6275         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6276         echo "$cmd"
6277         eval $cmd || error "$cmd failed"
6278
6279         for j in $(seq $NUMFILES); do
6280                 check_stripe_count $dir/dir1/file$j $expected
6281         done
6282
6283         # lfs_migrate works with lfs find
6284         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6285              $LFS_MIGRATE -y -c $expected"
6286         echo "$cmd"
6287         eval $cmd || error "$cmd failed"
6288
6289         for i in $(seq 2 $NUMFILES); do
6290                 check_stripe_count $dir/file$i $expected
6291         done
6292         for i in $(seq 2 $NUMDIRS); do
6293                 for j in $(seq $NUMFILES); do
6294                 check_stripe_count $dir/dir$i/file$j $expected
6295                 done
6296         done
6297 }
6298 run_test 56w "check lfs_migrate -c stripe_count works"
6299
6300 test_56wb() {
6301         local file1=$DIR/$tdir/file1
6302         local create_pool=false
6303         local initial_pool=$($LFS getstripe -p $DIR)
6304         local pool_list=()
6305         local pool=""
6306
6307         echo -n "Creating test dir..."
6308         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6309         echo "done."
6310
6311         echo -n "Creating test file..."
6312         touch $file1 || error "cannot create file"
6313         echo "done."
6314
6315         echo -n "Detecting existing pools..."
6316         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6317
6318         if [ ${#pool_list[@]} -gt 0 ]; then
6319                 echo "${pool_list[@]}"
6320                 for thispool in "${pool_list[@]}"; do
6321                         if [[ -z "$initial_pool" ||
6322                               "$initial_pool" != "$thispool" ]]; then
6323                                 pool="$thispool"
6324                                 echo "Using existing pool '$pool'"
6325                                 break
6326                         fi
6327                 done
6328         else
6329                 echo "none detected."
6330         fi
6331         if [ -z "$pool" ]; then
6332                 pool=${POOL:-testpool}
6333                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6334                 echo -n "Creating pool '$pool'..."
6335                 create_pool=true
6336                 pool_add $pool &> /dev/null ||
6337                         error "pool_add failed"
6338                 echo "done."
6339
6340                 echo -n "Adding target to pool..."
6341                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6342                         error "pool_add_targets failed"
6343                 echo "done."
6344         fi
6345
6346         echo -n "Setting pool using -p option..."
6347         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6348                 error "migrate failed rc = $?"
6349         echo "done."
6350
6351         echo -n "Verifying test file is in pool after migrating..."
6352         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6353                 error "file was not migrated to pool $pool"
6354         echo "done."
6355
6356         echo -n "Removing test file from pool '$pool'..."
6357         $LFS migrate $file1 &> /dev/null ||
6358                 error "cannot remove from pool"
6359         [ "$($LFS getstripe -p $file1)" ] &&
6360                 error "pool still set"
6361         echo "done."
6362
6363         echo -n "Setting pool using --pool option..."
6364         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6365                 error "migrate failed rc = $?"
6366         echo "done."
6367
6368         # Clean up
6369         rm -f $file1
6370         if $create_pool; then
6371                 destroy_test_pools 2> /dev/null ||
6372                         error "destroy test pools failed"
6373         fi
6374 }
6375 run_test 56wb "check lfs_migrate pool support"
6376
6377 test_56wc() {
6378         local file1="$DIR/$tdir/file1"
6379
6380         echo -n "Creating test dir..."
6381         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6382         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6383         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6384                 error "cannot set stripe"
6385         echo "done"
6386
6387         echo -n "Setting initial stripe for test file..."
6388         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6389                 error "cannot set stripe"
6390         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6391                 error "stripe size not set"
6392         echo "done."
6393
6394         # File currently set to -S 512K -c 1
6395
6396         # Ensure -c and -S options are rejected when -R is set
6397         echo -n "Verifying incompatible options are detected..."
6398         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6399                 error "incompatible -c and -R options not detected"
6400         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6401                 error "incompatible -S and -R options not detected"
6402         echo "done."
6403
6404         # Ensure unrecognized options are passed through to 'lfs migrate'
6405         echo -n "Verifying -S option is passed through to lfs migrate..."
6406         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6407                 error "migration failed"
6408         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6409                 error "file was not restriped"
6410         echo "done."
6411
6412         # File currently set to -S 1M -c 1
6413
6414         # Ensure long options are supported
6415         echo -n "Verifying long options supported..."
6416         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6417                 error "long option without argument not supported"
6418         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6419                 error "long option with argument not supported"
6420         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6421                 error "file not restriped with --stripe-size option"
6422         echo "done."
6423
6424         # File currently set to -S 512K -c 1
6425
6426         if [ "$OSTCOUNT" -gt 1 ]; then
6427                 echo -n "Verifying explicit stripe count can be set..."
6428                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6429                         error "migrate failed"
6430                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6431                         error "file not restriped to explicit count"
6432                 echo "done."
6433         fi
6434
6435         # File currently set to -S 512K -c 1 or -S 512K -c 2
6436
6437         # Ensure parent striping is used if -R is set, and no stripe
6438         # count or size is specified
6439         echo -n "Setting stripe for parent directory..."
6440         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6441                 error "cannot set stripe"
6442         echo "done."
6443
6444         echo -n "Verifying restripe option uses parent stripe settings..."
6445         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6446                 error "migrate failed"
6447         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6448                 error "file not restriped to parent settings"
6449         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6450                 error "file not restriped to parent settings"
6451         echo "done."
6452
6453         # File currently set to -S 1M -c 1
6454
6455         # Ensure striping is preserved if -R is not set, and no stripe
6456         # count or size is specified
6457         echo -n "Verifying striping size preserved when not specified..."
6458         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6459         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6460                 error "cannot set stripe on parent directory"
6461         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6462                 error "migrate failed"
6463         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6464                 error "file was restriped"
6465         echo "done."
6466
6467         # Ensure file name properly detected when final option has no argument
6468         echo -n "Verifying file name properly detected..."
6469         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6470                 error "file name interpreted as option argument"
6471         echo "done."
6472
6473         # Clean up
6474         rm -f "$file1"
6475 }
6476 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6477
6478 test_56wd() {
6479         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6480
6481         local file1=$DIR/$tdir/file1
6482
6483         echo -n "Creating test dir..."
6484         test_mkdir $DIR/$tdir || error "cannot create dir"
6485         echo "done."
6486
6487         echo -n "Creating test file..."
6488         touch $file1
6489         echo "done."
6490
6491         # Ensure 'lfs migrate' will fail by using a non-existent option,
6492         # and make sure rsync is not called to recover
6493         echo -n "Make sure --no-rsync option works..."
6494         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6495                 grep -q 'refusing to fall back to rsync' ||
6496                 error "rsync was called with --no-rsync set"
6497         echo "done."
6498
6499         # Ensure rsync is called without trying 'lfs migrate' first
6500         echo -n "Make sure --rsync option works..."
6501         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6502                 grep -q 'falling back to rsync' &&
6503                 error "lfs migrate was called with --rsync set"
6504         echo "done."
6505
6506         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6507         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6508                 grep -q 'at the same time' ||
6509                 error "--rsync and --no-rsync accepted concurrently"
6510         echo "done."
6511
6512         # Clean up
6513         rm -f $file1
6514 }
6515 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6516
6517 test_56x() {
6518         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6519         check_swap_layouts_support
6520
6521         local dir=$DIR/$tdir
6522         local ref1=/etc/passwd
6523         local file1=$dir/file1
6524
6525         test_mkdir $dir || error "creating dir $dir"
6526         $LFS setstripe -c 2 $file1
6527         cp $ref1 $file1
6528         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6529         stripe=$($LFS getstripe -c $file1)
6530         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6531         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6532
6533         # clean up
6534         rm -f $file1
6535 }
6536 run_test 56x "lfs migration support"
6537
6538 test_56xa() {
6539         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6540         check_swap_layouts_support
6541
6542         local dir=$DIR/$tdir/$testnum
6543
6544         test_mkdir -p $dir
6545
6546         local ref1=/etc/passwd
6547         local file1=$dir/file1
6548
6549         $LFS setstripe -c 2 $file1
6550         cp $ref1 $file1
6551         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6552
6553         local stripe=$($LFS getstripe -c $file1)
6554
6555         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6556         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6557
6558         # clean up
6559         rm -f $file1
6560 }
6561 run_test 56xa "lfs migration --block support"
6562
6563 check_migrate_links() {
6564         local dir="$1"
6565         local file1="$dir/file1"
6566         local begin="$2"
6567         local count="$3"
6568         local total_count=$(($begin + $count - 1))
6569         local symlink_count=10
6570         local uniq_count=10
6571
6572         if [ ! -f "$file1" ]; then
6573                 echo -n "creating initial file..."
6574                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6575                         error "cannot setstripe initial file"
6576                 echo "done"
6577
6578                 echo -n "creating symlinks..."
6579                 for s in $(seq 1 $symlink_count); do
6580                         ln -s "$file1" "$dir/slink$s" ||
6581                                 error "cannot create symlinks"
6582                 done
6583                 echo "done"
6584
6585                 echo -n "creating nonlinked files..."
6586                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6587                         error "cannot create nonlinked files"
6588                 echo "done"
6589         fi
6590
6591         # create hard links
6592         if [ ! -f "$dir/file$total_count" ]; then
6593                 echo -n "creating hard links $begin:$total_count..."
6594                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6595                         /dev/null || error "cannot create hard links"
6596                 echo "done"
6597         fi
6598
6599         echo -n "checking number of hard links listed in xattrs..."
6600         local fid=$($LFS getstripe -F "$file1")
6601         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6602
6603         echo "${#paths[*]}"
6604         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6605                         skip "hard link list has unexpected size, skipping test"
6606         fi
6607         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6608                         error "link names should exceed xattrs size"
6609         fi
6610
6611         echo -n "migrating files..."
6612         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
6613         local rc=$?
6614         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6615         echo "done"
6616
6617         # make sure all links have been properly migrated
6618         echo -n "verifying files..."
6619         fid=$($LFS getstripe -F "$file1") ||
6620                 error "cannot get fid for file $file1"
6621         for i in $(seq 2 $total_count); do
6622                 local fid2=$($LFS getstripe -F $dir/file$i)
6623
6624                 [ "$fid2" == "$fid" ] ||
6625                         error "migrated hard link has mismatched FID"
6626         done
6627
6628         # make sure hard links were properly detected, and migration was
6629         # performed only once for the entire link set; nonlinked files should
6630         # also be migrated
6631         local actual=$(grep -c 'done' <<< "$migrate_out")
6632         local expected=$(($uniq_count + 1))
6633
6634         [ "$actual" -eq  "$expected" ] ||
6635                 error "hard links individually migrated ($actual != $expected)"
6636
6637         # make sure the correct number of hard links are present
6638         local hardlinks=$(stat -c '%h' "$file1")
6639
6640         [ $hardlinks -eq $total_count ] ||
6641                 error "num hard links $hardlinks != $total_count"
6642         echo "done"
6643
6644         return 0
6645 }
6646
6647 test_56xb() {
6648         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6649                 skip "Need MDS version at least 2.10.55"
6650
6651         local dir="$DIR/$tdir"
6652
6653         test_mkdir "$dir" || error "cannot create dir $dir"
6654
6655         echo "testing lfs migrate mode when all links fit within xattrs"
6656         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6657
6658         echo "testing rsync mode when all links fit within xattrs"
6659         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6660
6661         echo "testing lfs migrate mode when all links do not fit within xattrs"
6662         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6663
6664         echo "testing rsync mode when all links do not fit within xattrs"
6665         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6666
6667
6668         # clean up
6669         rm -rf $dir
6670 }
6671 run_test 56xb "lfs migration hard link support"
6672
6673 test_56xc() {
6674         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6675
6676         local dir="$DIR/$tdir"
6677
6678         test_mkdir "$dir" || error "cannot create dir $dir"
6679
6680         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6681         echo -n "Setting initial stripe for 20MB test file..."
6682         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6683                 error "cannot setstripe 20MB file"
6684         echo "done"
6685         echo -n "Sizing 20MB test file..."
6686         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6687         echo "done"
6688         echo -n "Verifying small file autostripe count is 1..."
6689         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6690                 error "cannot migrate 20MB file"
6691         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6692                 error "cannot get stripe for $dir/20mb"
6693         [ $stripe_count -eq 1 ] ||
6694                 error "unexpected stripe count $stripe_count for 20MB file"
6695         rm -f "$dir/20mb"
6696         echo "done"
6697
6698         # Test 2: File is small enough to fit within the available space on
6699         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6700         # have at least an additional 1KB for each desired stripe for test 3
6701         echo -n "Setting stripe for 1GB test file..."
6702         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
6703         echo "done"
6704         echo -n "Sizing 1GB test file..."
6705         # File size is 1GB + 3KB
6706         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
6707         echo "done"
6708
6709         # need at least 512MB per OST for 1GB file to fit in 2 stripes
6710         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
6711         if (( avail > 524288 * OSTCOUNT )); then
6712                 echo -n "Migrating 1GB file..."
6713                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
6714                         error "cannot migrate 1GB file"
6715                 echo "done"
6716                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
6717                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6718                         error "cannot getstripe for 1GB file"
6719                 [ $stripe_count -eq 2 ] ||
6720                         error "unexpected stripe count $stripe_count != 2"
6721                 echo "done"
6722         fi
6723
6724         # Test 3: File is too large to fit within the available space on
6725         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6726         if [ $OSTCOUNT -ge 3 ]; then
6727                 # The required available space is calculated as
6728                 # file size (1GB + 3KB) / OST count (3).
6729                 local kb_per_ost=349526
6730
6731                 echo -n "Migrating 1GB file with limit..."
6732                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
6733                         error "cannot migrate 1GB file with limit"
6734                 echo "done"
6735
6736                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6737                 echo -n "Verifying 1GB autostripe count with limited space..."
6738                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
6739                         error "unexpected stripe count $stripe_count (min 3)"
6740                 echo "done"
6741         fi
6742
6743         # clean up
6744         rm -rf $dir
6745 }
6746 run_test 56xc "lfs migration autostripe"
6747
6748 test_56y() {
6749         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6750                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6751
6752         local res=""
6753         local dir=$DIR/$tdir
6754         local f1=$dir/file1
6755         local f2=$dir/file2
6756
6757         test_mkdir -p $dir || error "creating dir $dir"
6758         touch $f1 || error "creating std file $f1"
6759         $MULTIOP $f2 H2c || error "creating released file $f2"
6760
6761         # a directory can be raid0, so ask only for files
6762         res=$($LFS find $dir -L raid0 -type f | wc -l)
6763         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6764
6765         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6766         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6767
6768         # only files can be released, so no need to force file search
6769         res=$($LFS find $dir -L released)
6770         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6771
6772         res=$($LFS find $dir -type f \! -L released)
6773         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6774 }
6775 run_test 56y "lfs find -L raid0|released"
6776
6777 test_56z() { # LU-4824
6778         # This checks to make sure 'lfs find' continues after errors
6779         # There are two classes of errors that should be caught:
6780         # - If multiple paths are provided, all should be searched even if one
6781         #   errors out
6782         # - If errors are encountered during the search, it should not terminate
6783         #   early
6784         local dir=$DIR/$tdir
6785         local i
6786
6787         test_mkdir $dir
6788         for i in d{0..9}; do
6789                 test_mkdir $dir/$i
6790                 touch $dir/$i/$tfile
6791         done
6792         $LFS find $DIR/non_existent_dir $dir &&
6793                 error "$LFS find did not return an error"
6794         # Make a directory unsearchable. This should NOT be the last entry in
6795         # directory order.  Arbitrarily pick the 6th entry
6796         chmod 700 $($LFS find $dir -type d | sed '6!d')
6797
6798         $RUNAS $LFS find $DIR/non_existent $dir
6799         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6800
6801         # The user should be able to see 10 directories and 9 files
6802         (( count == 19 )) ||
6803                 error "$LFS find found $count != 19 entries after error"
6804 }
6805 run_test 56z "lfs find should continue after an error"
6806
6807 test_56aa() { # LU-5937
6808         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6809
6810         local dir=$DIR/$tdir
6811
6812         mkdir $dir
6813         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6814
6815         createmany -o $dir/striped_dir/${tfile}- 1024
6816         local dirs=$($LFS find --size +8k $dir/)
6817
6818         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6819 }
6820 run_test 56aa "lfs find --size under striped dir"
6821
6822 test_56ab() { # LU-10705
6823         test_mkdir $DIR/$tdir
6824         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6825         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6826         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6827         # Flush writes to ensure valid blocks.  Need to be more thorough for
6828         # ZFS, since blocks are not allocated/returned to client immediately.
6829         sync_all_data
6830         wait_zfs_commit ost1 2
6831         cancel_lru_locks osc
6832         ls -ls $DIR/$tdir
6833
6834         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6835
6836         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6837
6838         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6839         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6840
6841         rm -f $DIR/$tdir/$tfile.[123]
6842 }
6843 run_test 56ab "lfs find --blocks"
6844
6845 test_56ba() {
6846         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6847                 skip "Need MDS version at least 2.10.50"
6848
6849         # Create composite files with one component
6850         local dir=$DIR/$tdir
6851
6852         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6853         # Create composite files with three components
6854         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6855         # Create non-composite files
6856         createmany -o $dir/${tfile}- 10
6857
6858         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6859
6860         [[ $nfiles == 10 ]] ||
6861                 error "lfs find -E 1M found $nfiles != 10 files"
6862
6863         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6864         [[ $nfiles == 25 ]] ||
6865                 error "lfs find ! -E 1M found $nfiles != 25 files"
6866
6867         # All files have a component that starts at 0
6868         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6869         [[ $nfiles == 35 ]] ||
6870                 error "lfs find --component-start 0 - $nfiles != 35 files"
6871
6872         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6873         [[ $nfiles == 15 ]] ||
6874                 error "lfs find --component-start 2M - $nfiles != 15 files"
6875
6876         # All files created here have a componenet that does not starts at 2M
6877         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6878         [[ $nfiles == 35 ]] ||
6879                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6880
6881         # Find files with a specified number of components
6882         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6883         [[ $nfiles == 15 ]] ||
6884                 error "lfs find --component-count 3 - $nfiles != 15 files"
6885
6886         # Remember non-composite files have a component count of zero
6887         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6888         [[ $nfiles == 10 ]] ||
6889                 error "lfs find --component-count 0 - $nfiles != 10 files"
6890
6891         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6892         [[ $nfiles == 20 ]] ||
6893                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6894
6895         # All files have a flag called "init"
6896         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6897         [[ $nfiles == 35 ]] ||
6898                 error "lfs find --component-flags init - $nfiles != 35 files"
6899
6900         # Multi-component files will have a component not initialized
6901         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6902         [[ $nfiles == 15 ]] ||
6903                 error "lfs find !--component-flags init - $nfiles != 15 files"
6904
6905         rm -rf $dir
6906
6907 }
6908 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6909
6910 test_56ca() {
6911         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6912                 skip "Need MDS version at least 2.10.57"
6913
6914         local td=$DIR/$tdir
6915         local tf=$td/$tfile
6916         local dir
6917         local nfiles
6918         local cmd
6919         local i
6920         local j
6921
6922         # create mirrored directories and mirrored files
6923         mkdir $td || error "mkdir $td failed"
6924         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6925         createmany -o $tf- 10 || error "create $tf- failed"
6926
6927         for i in $(seq 2); do
6928                 dir=$td/dir$i
6929                 mkdir $dir || error "mkdir $dir failed"
6930                 $LFS mirror create -N$((3 + i)) $dir ||
6931                         error "create mirrored dir $dir failed"
6932                 createmany -o $dir/$tfile- 10 ||
6933                         error "create $dir/$tfile- failed"
6934         done
6935
6936         # change the states of some mirrored files
6937         echo foo > $tf-6
6938         for i in $(seq 2); do
6939                 dir=$td/dir$i
6940                 for j in $(seq 4 9); do
6941                         echo foo > $dir/$tfile-$j
6942                 done
6943         done
6944
6945         # find mirrored files with specific mirror count
6946         cmd="$LFS find --mirror-count 3 --type f $td"
6947         nfiles=$($cmd | wc -l)
6948         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6949
6950         cmd="$LFS find ! --mirror-count 3 --type f $td"
6951         nfiles=$($cmd | wc -l)
6952         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6953
6954         cmd="$LFS find --mirror-count +2 --type f $td"
6955         nfiles=$($cmd | wc -l)
6956         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6957
6958         cmd="$LFS find --mirror-count -6 --type f $td"
6959         nfiles=$($cmd | wc -l)
6960         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6961
6962         # find mirrored files with specific file state
6963         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6964         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6965
6966         cmd="$LFS find --mirror-state=ro --type f $td"
6967         nfiles=$($cmd | wc -l)
6968         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6969
6970         cmd="$LFS find ! --mirror-state=ro --type f $td"
6971         nfiles=$($cmd | wc -l)
6972         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6973
6974         cmd="$LFS find --mirror-state=wp --type f $td"
6975         nfiles=$($cmd | wc -l)
6976         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6977
6978         cmd="$LFS find ! --mirror-state=sp --type f $td"
6979         nfiles=$($cmd | wc -l)
6980         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6981 }
6982 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6983
6984 test_57a() {
6985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6986         # note test will not do anything if MDS is not local
6987         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6988                 skip_env "ldiskfs only test"
6989         fi
6990         remote_mds_nodsh && skip "remote MDS with nodsh"
6991
6992         local MNTDEV="osd*.*MDT*.mntdev"
6993         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6994         [ -z "$DEV" ] && error "can't access $MNTDEV"
6995         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6996                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6997                         error "can't access $DEV"
6998                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6999                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7000                 rm $TMP/t57a.dump
7001         done
7002 }
7003 run_test 57a "verify MDS filesystem created with large inodes =="
7004
7005 test_57b() {
7006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7007         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7008                 skip_env "ldiskfs only test"
7009         fi
7010         remote_mds_nodsh && skip "remote MDS with nodsh"
7011
7012         local dir=$DIR/$tdir
7013         local filecount=100
7014         local file1=$dir/f1
7015         local fileN=$dir/f$filecount
7016
7017         rm -rf $dir || error "removing $dir"
7018         test_mkdir -c1 $dir
7019         local mdtidx=$($LFS getstripe -m $dir)
7020         local mdtname=MDT$(printf %04x $mdtidx)
7021         local facet=mds$((mdtidx + 1))
7022
7023         echo "mcreating $filecount files"
7024         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7025
7026         # verify that files do not have EAs yet
7027         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7028                 error "$file1 has an EA"
7029         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7030                 error "$fileN has an EA"
7031
7032         sync
7033         sleep 1
7034         df $dir  #make sure we get new statfs data
7035         local mdsfree=$(do_facet $facet \
7036                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7037         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7038         local file
7039
7040         echo "opening files to create objects/EAs"
7041         for file in $(seq -f $dir/f%g 1 $filecount); do
7042                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7043                         error "opening $file"
7044         done
7045
7046         # verify that files have EAs now
7047         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7048         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7049
7050         sleep 1  #make sure we get new statfs data
7051         df $dir
7052         local mdsfree2=$(do_facet $facet \
7053                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7054         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7055
7056         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7057                 if [ "$mdsfree" != "$mdsfree2" ]; then
7058                         error "MDC before $mdcfree != after $mdcfree2"
7059                 else
7060                         echo "MDC before $mdcfree != after $mdcfree2"
7061                         echo "unable to confirm if MDS has large inodes"
7062                 fi
7063         fi
7064         rm -rf $dir
7065 }
7066 run_test 57b "default LOV EAs are stored inside large inodes ==="
7067
7068 test_58() {
7069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7070         [ -z "$(which wiretest 2>/dev/null)" ] &&
7071                         skip_env "could not find wiretest"
7072
7073         wiretest
7074 }
7075 run_test 58 "verify cross-platform wire constants =============="
7076
7077 test_59() {
7078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7079
7080         echo "touch 130 files"
7081         createmany -o $DIR/f59- 130
7082         echo "rm 130 files"
7083         unlinkmany $DIR/f59- 130
7084         sync
7085         # wait for commitment of removal
7086         wait_delete_completed
7087 }
7088 run_test 59 "verify cancellation of llog records async ========="
7089
7090 TEST60_HEAD="test_60 run $RANDOM"
7091 test_60a() {
7092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7093         remote_mgs_nodsh && skip "remote MGS with nodsh"
7094         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7095                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7096                         skip_env "missing subtest run-llog.sh"
7097
7098         log "$TEST60_HEAD - from kernel mode"
7099         do_facet mgs "$LCTL dk > /dev/null"
7100         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7101         do_facet mgs $LCTL dk > $TMP/$tfile
7102
7103         # LU-6388: test llog_reader
7104         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7105         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7106         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7107                         skip_env "missing llog_reader"
7108         local fstype=$(facet_fstype mgs)
7109         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7110                 skip_env "Only for ldiskfs or zfs type mgs"
7111
7112         local mntpt=$(facet_mntpt mgs)
7113         local mgsdev=$(mgsdevname 1)
7114         local fid_list
7115         local fid
7116         local rec_list
7117         local rec
7118         local rec_type
7119         local obj_file
7120         local path
7121         local seq
7122         local oid
7123         local pass=true
7124
7125         #get fid and record list
7126         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7127                 tail -n 4))
7128         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7129                 tail -n 4))
7130         #remount mgs as ldiskfs or zfs type
7131         stop mgs || error "stop mgs failed"
7132         mount_fstype mgs || error "remount mgs failed"
7133         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7134                 fid=${fid_list[i]}
7135                 rec=${rec_list[i]}
7136                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7137                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7138                 oid=$((16#$oid))
7139
7140                 case $fstype in
7141                         ldiskfs )
7142                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7143                         zfs )
7144                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7145                 esac
7146                 echo "obj_file is $obj_file"
7147                 do_facet mgs $llog_reader $obj_file
7148
7149                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7150                         awk '{ print $3 }' | sed -e "s/^type=//g")
7151                 if [ $rec_type != $rec ]; then
7152                         echo "FAILED test_60a wrong record type $rec_type," \
7153                               "should be $rec"
7154                         pass=false
7155                         break
7156                 fi
7157
7158                 #check obj path if record type is LLOG_LOGID_MAGIC
7159                 if [ "$rec" == "1064553b" ]; then
7160                         path=$(do_facet mgs $llog_reader $obj_file |
7161                                 grep "path=" | awk '{ print $NF }' |
7162                                 sed -e "s/^path=//g")
7163                         if [ $obj_file != $mntpt/$path ]; then
7164                                 echo "FAILED test_60a wrong obj path" \
7165                                       "$montpt/$path, should be $obj_file"
7166                                 pass=false
7167                                 break
7168                         fi
7169                 fi
7170         done
7171         rm -f $TMP/$tfile
7172         #restart mgs before "error", otherwise it will block the next test
7173         stop mgs || error "stop mgs failed"
7174         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7175         $pass || error "test failed, see FAILED test_60a messages for specifics"
7176 }
7177 run_test 60a "llog_test run from kernel module and test llog_reader"
7178
7179 test_60b() { # bug 6411
7180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7181
7182         dmesg > $DIR/$tfile
7183         LLOG_COUNT=$(do_facet mgs dmesg |
7184                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7185                           /llog_[a-z]*.c:[0-9]/ {
7186                                 if (marker)
7187                                         from_marker++
7188                                 from_begin++
7189                           }
7190                           END {
7191                                 if (marker)
7192                                         print from_marker
7193                                 else
7194                                         print from_begin
7195                           }")
7196
7197         [[ $LLOG_COUNT -gt 120 ]] &&
7198                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7199 }
7200 run_test 60b "limit repeated messages from CERROR/CWARN"
7201
7202 test_60c() {
7203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7204
7205         echo "create 5000 files"
7206         createmany -o $DIR/f60c- 5000
7207 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7208         lctl set_param fail_loc=0x80000137
7209         unlinkmany $DIR/f60c- 5000
7210         lctl set_param fail_loc=0
7211 }
7212 run_test 60c "unlink file when mds full"
7213
7214 test_60d() {
7215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7216
7217         SAVEPRINTK=$(lctl get_param -n printk)
7218         # verify "lctl mark" is even working"
7219         MESSAGE="test message ID $RANDOM $$"
7220         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7221         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7222
7223         lctl set_param printk=0 || error "set lnet.printk failed"
7224         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7225         MESSAGE="new test message ID $RANDOM $$"
7226         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7227         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7228         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7229
7230         lctl set_param -n printk="$SAVEPRINTK"
7231 }
7232 run_test 60d "test printk console message masking"
7233
7234 test_60e() {
7235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7236         remote_mds_nodsh && skip "remote MDS with nodsh"
7237
7238         touch $DIR/$tfile
7239 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7240         do_facet mds1 lctl set_param fail_loc=0x15b
7241         rm $DIR/$tfile
7242 }
7243 run_test 60e "no space while new llog is being created"
7244
7245 test_60g() {
7246         local pid
7247         local i
7248
7249         test_mkdir -c $MDSCOUNT $DIR/$tdir
7250
7251         (
7252                 local index=0
7253                 while true; do
7254                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7255                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7256                                 2>/dev/null
7257                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7258                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7259                         index=$((index + 1))
7260                 done
7261         ) &
7262
7263         pid=$!
7264
7265         for i in {0..100}; do
7266                 # define OBD_FAIL_OSD_TXN_START    0x19a
7267                 local index=$((i % MDSCOUNT + 1))
7268
7269                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7270                         > /dev/null
7271                 usleep 100
7272         done
7273
7274         kill -9 $pid
7275
7276         for i in $(seq $MDSCOUNT); do
7277                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7278         done
7279
7280         mkdir $DIR/$tdir/new || error "mkdir failed"
7281         rmdir $DIR/$tdir/new || error "rmdir failed"
7282
7283         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7284                 -t namespace
7285         for i in $(seq $MDSCOUNT); do
7286                 wait_update_facet mds$i "$LCTL get_param -n \
7287                         mdd.$(facet_svc mds$i).lfsck_namespace |
7288                         awk '/^status/ { print \\\$2 }'" "completed"
7289         done
7290
7291         ls -R $DIR/$tdir || error "ls failed"
7292         rm -rf $DIR/$tdir || error "rmdir failed"
7293 }
7294 run_test 60g "transaction abort won't cause MDT hung"
7295
7296 test_60h() {
7297         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7298                 skip "Need MDS version at least 2.12.52"
7299         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7300
7301         local f
7302
7303         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7304         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7305         for fail_loc in 0x80000188 0x80000189; do
7306                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7307                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7308                         error "mkdir $dir-$fail_loc failed"
7309                 for i in {0..10}; do
7310                         # create may fail on missing stripe
7311                         echo $i > $DIR/$tdir-$fail_loc/$i
7312                 done
7313                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7314                         error "getdirstripe $tdir-$fail_loc failed"
7315                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7316                         error "migrate $tdir-$fail_loc failed"
7317                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7318                         error "getdirstripe $tdir-$fail_loc failed"
7319                 pushd $DIR/$tdir-$fail_loc
7320                 for f in *; do
7321                         echo $f | cmp $f - || error "$f data mismatch"
7322                 done
7323                 popd
7324                 rm -rf $DIR/$tdir-$fail_loc
7325         done
7326 }
7327 run_test 60h "striped directory with missing stripes can be accessed"
7328
7329 test_61a() {
7330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7331
7332         f="$DIR/f61"
7333         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7334         cancel_lru_locks osc
7335         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7336         sync
7337 }
7338 run_test 61a "mmap() writes don't make sync hang ================"
7339
7340 test_61b() {
7341         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7342 }
7343 run_test 61b "mmap() of unstriped file is successful"
7344
7345 # bug 2330 - insufficient obd_match error checking causes LBUG
7346 test_62() {
7347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7348
7349         f="$DIR/f62"
7350         echo foo > $f
7351         cancel_lru_locks osc
7352         lctl set_param fail_loc=0x405
7353         cat $f && error "cat succeeded, expect -EIO"
7354         lctl set_param fail_loc=0
7355 }
7356 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7357 # match every page all of the time.
7358 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7359
7360 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7361 # Though this test is irrelevant anymore, it helped to reveal some
7362 # other grant bugs (LU-4482), let's keep it.
7363 test_63a() {   # was test_63
7364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7365
7366         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7367
7368         for i in `seq 10` ; do
7369                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7370                 sleep 5
7371                 kill $!
7372                 sleep 1
7373         done
7374
7375         rm -f $DIR/f63 || true
7376 }
7377 run_test 63a "Verify oig_wait interruption does not crash ======="
7378
7379 # bug 2248 - async write errors didn't return to application on sync
7380 # bug 3677 - async write errors left page locked
7381 test_63b() {
7382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7383
7384         debugsave
7385         lctl set_param debug=-1
7386
7387         # ensure we have a grant to do async writes
7388         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7389         rm $DIR/$tfile
7390
7391         sync    # sync lest earlier test intercept the fail_loc
7392
7393         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7394         lctl set_param fail_loc=0x80000406
7395         $MULTIOP $DIR/$tfile Owy && \
7396                 error "sync didn't return ENOMEM"
7397         sync; sleep 2; sync     # do a real sync this time to flush page
7398         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7399                 error "locked page left in cache after async error" || true
7400         debugrestore
7401 }
7402 run_test 63b "async write errors should be returned to fsync ==="
7403
7404 test_64a () {
7405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7406
7407         df $DIR
7408         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7409 }
7410 run_test 64a "verify filter grant calculations (in kernel) ====="
7411
7412 test_64b () {
7413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7414
7415         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7416 }
7417 run_test 64b "check out-of-space detection on client"
7418
7419 test_64c() {
7420         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7421 }
7422 run_test 64c "verify grant shrink"
7423
7424 # this does exactly what osc_request.c:osc_announce_cached() does in
7425 # order to calculate max amount of grants to ask from server
7426 want_grant() {
7427         local tgt=$1
7428
7429         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7430         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7431
7432         ((rpc_in_flight ++));
7433         nrpages=$((nrpages * rpc_in_flight))
7434
7435         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7436
7437         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7438
7439         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7440         local undirty=$((nrpages * PAGE_SIZE))
7441
7442         local max_extent_pages
7443         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7444             grep grant_max_extent_size | awk '{print $2}')
7445         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7446         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7447         local grant_extent_tax
7448         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7449             grep grant_extent_tax | awk '{print $2}')
7450
7451         undirty=$((undirty + nrextents * grant_extent_tax))
7452
7453         echo $undirty
7454 }
7455
7456 # this is size of unit for grant allocation. It should be equal to
7457 # what tgt_grant.c:tgt_grant_chunk() calculates
7458 grant_chunk() {
7459         local tgt=$1
7460         local max_brw_size
7461         local grant_extent_tax
7462
7463         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7464             grep max_brw_size | awk '{print $2}')
7465
7466         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7467             grep grant_extent_tax | awk '{print $2}')
7468
7469         echo $(((max_brw_size + grant_extent_tax) * 2))
7470 }
7471
7472 test_64d() {
7473         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7474                 skip "OST < 2.10.55 doesn't limit grants enough"
7475
7476         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7477         local file=$DIR/$tfile
7478
7479         [[ $($LCTL get_param osc.${tgt}.import |
7480              grep "connect_flags:.*grant_param") ]] ||
7481                 skip "no grant_param connect flag"
7482
7483         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7484
7485         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7486
7487         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7488         stack_trap "rm -f $file" EXIT
7489
7490         $LFS setstripe $file -i 0 -c 1
7491         dd if=/dev/zero of=$file bs=1M count=1000 &
7492         ddpid=$!
7493
7494         while true
7495         do
7496                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7497                 if [[ $cur_grant -gt $max_cur_granted ]]
7498                 then
7499                         kill $ddpid
7500                         error "cur_grant $cur_grant > $max_cur_granted"
7501                 fi
7502                 kill -0 $ddpid
7503                 [[ $? -ne 0 ]] && break;
7504                 sleep 2
7505         done
7506
7507         rm -f $DIR/$tfile
7508         wait_delete_completed
7509         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7510 }
7511 run_test 64d "check grant limit exceed"
7512
7513 # bug 1414 - set/get directories' stripe info
7514 test_65a() {
7515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7516
7517         test_mkdir $DIR/$tdir
7518         touch $DIR/$tdir/f1
7519         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7520 }
7521 run_test 65a "directory with no stripe info"
7522
7523 test_65b() {
7524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7525
7526         test_mkdir $DIR/$tdir
7527         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7528
7529         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7530                                                 error "setstripe"
7531         touch $DIR/$tdir/f2
7532         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7533 }
7534 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7535
7536 test_65c() {
7537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7538         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7539
7540         test_mkdir $DIR/$tdir
7541         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7542
7543         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7544                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7545         touch $DIR/$tdir/f3
7546         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7547 }
7548 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7549
7550 test_65d() {
7551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7552
7553         test_mkdir $DIR/$tdir
7554         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7555         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7556
7557         if [[ $STRIPECOUNT -le 0 ]]; then
7558                 sc=1
7559         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7560                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7561                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7562         else
7563                 sc=$(($STRIPECOUNT - 1))
7564         fi
7565         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7566         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7567         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7568                 error "lverify failed"
7569 }
7570 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7571
7572 test_65e() {
7573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7574
7575         test_mkdir $DIR/$tdir
7576
7577         $LFS setstripe $DIR/$tdir || error "setstripe"
7578         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7579                                         error "no stripe info failed"
7580         touch $DIR/$tdir/f6
7581         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7582 }
7583 run_test 65e "directory setstripe defaults"
7584
7585 test_65f() {
7586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7587
7588         test_mkdir $DIR/${tdir}f
7589         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7590                 error "setstripe succeeded" || true
7591 }
7592 run_test 65f "dir setstripe permission (should return error) ==="
7593
7594 test_65g() {
7595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7596
7597         test_mkdir $DIR/$tdir
7598         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7599
7600         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7601                 error "setstripe -S failed"
7602         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7603         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7604                 error "delete default stripe failed"
7605 }
7606 run_test 65g "directory setstripe -d"
7607
7608 test_65h() {
7609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7610
7611         test_mkdir $DIR/$tdir
7612         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7613
7614         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7615                 error "setstripe -S failed"
7616         test_mkdir $DIR/$tdir/dd1
7617         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7618                 error "stripe info inherit failed"
7619 }
7620 run_test 65h "directory stripe info inherit ===================="
7621
7622 test_65i() {
7623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7624
7625         save_layout_restore_at_exit $MOUNT
7626
7627         # bug6367: set non-default striping on root directory
7628         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7629
7630         # bug12836: getstripe on -1 default directory striping
7631         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7632
7633         # bug12836: getstripe -v on -1 default directory striping
7634         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7635
7636         # bug12836: new find on -1 default directory striping
7637         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7638 }
7639 run_test 65i "various tests to set root directory striping"
7640
7641 test_65j() { # bug6367
7642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7643
7644         sync; sleep 1
7645
7646         # if we aren't already remounting for each test, do so for this test
7647         if [ "$I_MOUNTED" = "yes" ]; then
7648                 cleanup || error "failed to unmount"
7649                 setup
7650         fi
7651
7652         save_layout_restore_at_exit $MOUNT
7653
7654         $LFS setstripe -d $MOUNT || error "setstripe failed"
7655 }
7656 run_test 65j "set default striping on root directory (bug 6367)="
7657
7658 cleanup_65k() {
7659         rm -rf $DIR/$tdir
7660         wait_delete_completed
7661         do_facet $SINGLEMDS "lctl set_param -n \
7662                 osp.$ost*MDT0000.max_create_count=$max_count"
7663         do_facet $SINGLEMDS "lctl set_param -n \
7664                 osp.$ost*MDT0000.create_count=$count"
7665         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7666         echo $INACTIVE_OSC "is Activate"
7667
7668         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7669 }
7670
7671 test_65k() { # bug11679
7672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7673         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7674         remote_mds_nodsh && skip "remote MDS with nodsh"
7675
7676         local disable_precreate=true
7677         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7678                 disable_precreate=false
7679
7680         echo "Check OST status: "
7681         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7682                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7683
7684         for OSC in $MDS_OSCS; do
7685                 echo $OSC "is active"
7686                 do_facet $SINGLEMDS lctl --device %$OSC activate
7687         done
7688
7689         for INACTIVE_OSC in $MDS_OSCS; do
7690                 local ost=$(osc_to_ost $INACTIVE_OSC)
7691                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7692                                lov.*md*.target_obd |
7693                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7694
7695                 mkdir -p $DIR/$tdir
7696                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7697                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7698
7699                 echo "Deactivate: " $INACTIVE_OSC
7700                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7701
7702                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7703                               osp.$ost*MDT0000.create_count")
7704                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7705                                   osp.$ost*MDT0000.max_create_count")
7706                 $disable_precreate &&
7707                         do_facet $SINGLEMDS "lctl set_param -n \
7708                                 osp.$ost*MDT0000.max_create_count=0"
7709
7710                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7711                         [ -f $DIR/$tdir/$idx ] && continue
7712                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7713                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7714                                 { cleanup_65k;
7715                                   error "setstripe $idx should succeed"; }
7716                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7717                 done
7718                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7719                 rmdir $DIR/$tdir
7720
7721                 do_facet $SINGLEMDS "lctl set_param -n \
7722                         osp.$ost*MDT0000.max_create_count=$max_count"
7723                 do_facet $SINGLEMDS "lctl set_param -n \
7724                         osp.$ost*MDT0000.create_count=$count"
7725                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7726                 echo $INACTIVE_OSC "is Activate"
7727
7728                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7729         done
7730 }
7731 run_test 65k "validate manual striping works properly with deactivated OSCs"
7732
7733 test_65l() { # bug 12836
7734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7735
7736         test_mkdir -p $DIR/$tdir/test_dir
7737         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7738         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7739 }
7740 run_test 65l "lfs find on -1 stripe dir ========================"
7741
7742 test_65m() {
7743         local layout=$(save_layout $MOUNT)
7744         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7745                 restore_layout $MOUNT $layout
7746                 error "setstripe should fail by non-root users"
7747         }
7748         true
7749 }
7750 run_test 65m "normal user can't set filesystem default stripe"
7751
7752 test_65n() {
7753         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7754         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7755                 skip "Need MDS version at least 2.12.50"
7756         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7757
7758         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7759         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7760         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7761
7762         local root_layout=$(save_layout $MOUNT)
7763         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7764
7765         # new subdirectory under root directory should not inherit
7766         # the default layout from root
7767         local dir1=$MOUNT/$tdir-1
7768         mkdir $dir1 || error "mkdir $dir1 failed"
7769         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7770                 error "$dir1 shouldn't have LOV EA"
7771
7772         # delete the default layout on root directory
7773         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7774
7775         local dir2=$MOUNT/$tdir-2
7776         mkdir $dir2 || error "mkdir $dir2 failed"
7777         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7778                 error "$dir2 shouldn't have LOV EA"
7779
7780         # set a new striping pattern on root directory
7781         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7782         local new_def_stripe_size=$((def_stripe_size * 2))
7783         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7784                 error "set stripe size on $MOUNT failed"
7785
7786         # new file created in $dir2 should inherit the new stripe size from
7787         # the filesystem default
7788         local file2=$dir2/$tfile-2
7789         touch $file2 || error "touch $file2 failed"
7790
7791         local file2_stripe_size=$($LFS getstripe -S $file2)
7792         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7793                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7794
7795         local dir3=$MOUNT/$tdir-3
7796         mkdir $dir3 || error "mkdir $dir3 failed"
7797         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7798                 error "$dir3 shouldn't have LOV EA"
7799
7800         # set OST pool on root directory
7801         local pool=$TESTNAME
7802         pool_add $pool || error "add $pool failed"
7803         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7804                 error "add targets to $pool failed"
7805
7806         $LFS setstripe -p $pool $MOUNT ||
7807                 error "set OST pool on $MOUNT failed"
7808
7809         # new file created in $dir3 should inherit the pool from
7810         # the filesystem default
7811         local file3=$dir3/$tfile-3
7812         touch $file3 || error "touch $file3 failed"
7813
7814         local file3_pool=$($LFS getstripe -p $file3)
7815         [[ "$file3_pool" = "$pool" ]] ||
7816                 error "$file3 didn't inherit OST pool $pool"
7817
7818         local dir4=$MOUNT/$tdir-4
7819         mkdir $dir4 || error "mkdir $dir4 failed"
7820         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7821                 error "$dir4 shouldn't have LOV EA"
7822
7823         # new file created in $dir4 should inherit the pool from
7824         # the filesystem default
7825         local file4=$dir4/$tfile-4
7826         touch $file4 || error "touch $file4 failed"
7827
7828         local file4_pool=$($LFS getstripe -p $file4)
7829         [[ "$file4_pool" = "$pool" ]] ||
7830                 error "$file4 didn't inherit OST pool $pool"
7831
7832         # new subdirectory under non-root directory should inherit
7833         # the default layout from its parent directory
7834         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7835                 error "set directory layout on $dir4 failed"
7836
7837         local dir5=$dir4/$tdir-5
7838         mkdir $dir5 || error "mkdir $dir5 failed"
7839
7840         local dir4_layout=$(get_layout_param $dir4)
7841         local dir5_layout=$(get_layout_param $dir5)
7842         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7843                 error "$dir5 should inherit the default layout from $dir4"
7844
7845         # though subdir under ROOT doesn't inherit default layout, but
7846         # its sub dir/file should be created with default layout.
7847         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
7848         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
7849                 skip "Need MDS version at least 2.12.59"
7850
7851         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
7852         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
7853         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
7854
7855         if [ $default_lmv_hash == "none" ]; then
7856                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
7857         else
7858                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
7859                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
7860         fi
7861
7862         $LFS setdirstripe -D -c 2 $MOUNT ||
7863                 error "setdirstripe -D -c 2 failed"
7864         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
7865         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
7866         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
7867 }
7868 run_test 65n "don't inherit default layout from root for new subdirectories"
7869
7870 # bug 2543 - update blocks count on client
7871 test_66() {
7872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7873
7874         COUNT=${COUNT:-8}
7875         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7876         sync; sync_all_data; sync; sync_all_data
7877         cancel_lru_locks osc
7878         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7879         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7880 }
7881 run_test 66 "update inode blocks count on client ==============="
7882
7883 meminfo() {
7884         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7885 }
7886
7887 swap_used() {
7888         swapon -s | awk '($1 == "'$1'") { print $4 }'
7889 }
7890
7891 # bug5265, obdfilter oa2dentry return -ENOENT
7892 # #define OBD_FAIL_SRV_ENOENT 0x217
7893 test_69() {
7894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7895         remote_ost_nodsh && skip "remote OST with nodsh"
7896
7897         f="$DIR/$tfile"
7898         $LFS setstripe -c 1 -i 0 $f
7899
7900         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7901
7902         do_facet ost1 lctl set_param fail_loc=0x217
7903         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7904         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7905
7906         do_facet ost1 lctl set_param fail_loc=0
7907         $DIRECTIO write $f 0 2 || error "write error"
7908
7909         cancel_lru_locks osc
7910         $DIRECTIO read $f 0 1 || error "read error"
7911
7912         do_facet ost1 lctl set_param fail_loc=0x217
7913         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7914
7915         do_facet ost1 lctl set_param fail_loc=0
7916         rm -f $f
7917 }
7918 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7919
7920 test_71() {
7921         test_mkdir $DIR/$tdir
7922         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7923         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7924 }
7925 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7926
7927 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7929         [ "$RUNAS_ID" = "$UID" ] &&
7930                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7931         # Check that testing environment is properly set up. Skip if not
7932         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7933                 skip_env "User $RUNAS_ID does not exist - skipping"
7934
7935         touch $DIR/$tfile
7936         chmod 777 $DIR/$tfile
7937         chmod ug+s $DIR/$tfile
7938         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7939                 error "$RUNAS dd $DIR/$tfile failed"
7940         # See if we are still setuid/sgid
7941         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7942                 error "S/gid is not dropped on write"
7943         # Now test that MDS is updated too
7944         cancel_lru_locks mdc
7945         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7946                 error "S/gid is not dropped on MDS"
7947         rm -f $DIR/$tfile
7948 }
7949 run_test 72a "Test that remove suid works properly (bug5695) ===="
7950
7951 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7952         local perm
7953
7954         [ "$RUNAS_ID" = "$UID" ] &&
7955                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7956         [ "$RUNAS_ID" -eq 0 ] &&
7957                 skip_env "RUNAS_ID = 0 -- skipping"
7958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7959         # Check that testing environment is properly set up. Skip if not
7960         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7961                 skip_env "User $RUNAS_ID does not exist - skipping"
7962
7963         touch $DIR/${tfile}-f{g,u}
7964         test_mkdir $DIR/${tfile}-dg
7965         test_mkdir $DIR/${tfile}-du
7966         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7967         chmod g+s $DIR/${tfile}-{f,d}g
7968         chmod u+s $DIR/${tfile}-{f,d}u
7969         for perm in 777 2777 4777; do
7970                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7971                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7972                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7973                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7974         done
7975         true
7976 }
7977 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7978
7979 # bug 3462 - multiple simultaneous MDC requests
7980 test_73() {
7981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7982
7983         test_mkdir $DIR/d73-1
7984         test_mkdir $DIR/d73-2
7985         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7986         pid1=$!
7987
7988         lctl set_param fail_loc=0x80000129
7989         $MULTIOP $DIR/d73-1/f73-2 Oc &
7990         sleep 1
7991         lctl set_param fail_loc=0
7992
7993         $MULTIOP $DIR/d73-2/f73-3 Oc &
7994         pid3=$!
7995
7996         kill -USR1 $pid1
7997         wait $pid1 || return 1
7998
7999         sleep 25
8000
8001         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8002         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8003         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8004
8005         rm -rf $DIR/d73-*
8006 }
8007 run_test 73 "multiple MDC requests (should not deadlock)"
8008
8009 test_74a() { # bug 6149, 6184
8010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8011
8012         touch $DIR/f74a
8013         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8014         #
8015         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8016         # will spin in a tight reconnection loop
8017         $LCTL set_param fail_loc=0x8000030e
8018         # get any lock that won't be difficult - lookup works.
8019         ls $DIR/f74a
8020         $LCTL set_param fail_loc=0
8021         rm -f $DIR/f74a
8022         true
8023 }
8024 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8025
8026 test_74b() { # bug 13310
8027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8028
8029         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8030         #
8031         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8032         # will spin in a tight reconnection loop
8033         $LCTL set_param fail_loc=0x8000030e
8034         # get a "difficult" lock
8035         touch $DIR/f74b
8036         $LCTL set_param fail_loc=0
8037         rm -f $DIR/f74b
8038         true
8039 }
8040 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8041
8042 test_74c() {
8043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8044
8045         #define OBD_FAIL_LDLM_NEW_LOCK
8046         $LCTL set_param fail_loc=0x319
8047         touch $DIR/$tfile && error "touch successful"
8048         $LCTL set_param fail_loc=0
8049         true
8050 }
8051 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8052
8053 num_inodes() {
8054         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8055 }
8056
8057 test_76() { # Now for bug 20433, added originally in bug 1443
8058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8059
8060         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8061
8062         cancel_lru_locks osc
8063         BEFORE_INODES=$(num_inodes)
8064         echo "before inodes: $BEFORE_INODES"
8065         local COUNT=1000
8066         [ "$SLOW" = "no" ] && COUNT=100
8067         for i in $(seq $COUNT); do
8068                 touch $DIR/$tfile
8069                 rm -f $DIR/$tfile
8070         done
8071         cancel_lru_locks osc
8072         AFTER_INODES=$(num_inodes)
8073         echo "after inodes: $AFTER_INODES"
8074         local wait=0
8075         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
8076                 sleep 2
8077                 AFTER_INODES=$(num_inodes)
8078                 wait=$((wait+2))
8079                 echo "wait $wait seconds inodes: $AFTER_INODES"
8080                 if [ $wait -gt 30 ]; then
8081                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
8082                 fi
8083         done
8084 }
8085 run_test 76 "confirm clients recycle inodes properly ===="
8086
8087
8088 export ORIG_CSUM=""
8089 set_checksums()
8090 {
8091         # Note: in sptlrpc modes which enable its own bulk checksum, the
8092         # original crc32_le bulk checksum will be automatically disabled,
8093         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8094         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8095         # In this case set_checksums() will not be no-op, because sptlrpc
8096         # bulk checksum will be enabled all through the test.
8097
8098         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8099         lctl set_param -n osc.*.checksums $1
8100         return 0
8101 }
8102
8103 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8104                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8105 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8106                              tr -d [] | head -n1)}
8107 set_checksum_type()
8108 {
8109         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8110         rc=$?
8111         log "set checksum type to $1, rc = $rc"
8112         return $rc
8113 }
8114
8115 get_osc_checksum_type()
8116 {
8117         # arugment 1: OST name, like OST0000
8118         ost=$1
8119         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8120                         sed 's/.*\[\(.*\)\].*/\1/g')
8121         rc=$?
8122         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8123         echo $checksum_type
8124 }
8125
8126 F77_TMP=$TMP/f77-temp
8127 F77SZ=8
8128 setup_f77() {
8129         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8130                 error "error writing to $F77_TMP"
8131 }
8132
8133 test_77a() { # bug 10889
8134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8135         $GSS && skip_env "could not run with gss"
8136
8137         [ ! -f $F77_TMP ] && setup_f77
8138         set_checksums 1
8139         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8140         set_checksums 0
8141         rm -f $DIR/$tfile
8142 }
8143 run_test 77a "normal checksum read/write operation"
8144
8145 test_77b() { # bug 10889
8146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8147         $GSS && skip_env "could not run with gss"
8148
8149         [ ! -f $F77_TMP ] && setup_f77
8150         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8151         $LCTL set_param fail_loc=0x80000409
8152         set_checksums 1
8153
8154         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8155                 error "dd error: $?"
8156         $LCTL set_param fail_loc=0
8157
8158         for algo in $CKSUM_TYPES; do
8159                 cancel_lru_locks osc
8160                 set_checksum_type $algo
8161                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8162                 $LCTL set_param fail_loc=0x80000408
8163                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8164                 $LCTL set_param fail_loc=0
8165         done
8166         set_checksums 0
8167         set_checksum_type $ORIG_CSUM_TYPE
8168         rm -f $DIR/$tfile
8169 }
8170 run_test 77b "checksum error on client write, read"
8171
8172 cleanup_77c() {
8173         trap 0
8174         set_checksums 0
8175         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8176         $check_ost &&
8177                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8178         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8179         $check_ost && [ -n "$ost_file_prefix" ] &&
8180                 do_facet ost1 rm -f ${ost_file_prefix}\*
8181 }
8182
8183 test_77c() {
8184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8185         $GSS && skip_env "could not run with gss"
8186         remote_ost_nodsh && skip "remote OST with nodsh"
8187
8188         local bad1
8189         local osc_file_prefix
8190         local osc_file
8191         local check_ost=false
8192         local ost_file_prefix
8193         local ost_file
8194         local orig_cksum
8195         local dump_cksum
8196         local fid
8197
8198         # ensure corruption will occur on first OSS/OST
8199         $LFS setstripe -i 0 $DIR/$tfile
8200
8201         [ ! -f $F77_TMP ] && setup_f77
8202         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8203                 error "dd write error: $?"
8204         fid=$($LFS path2fid $DIR/$tfile)
8205
8206         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8207         then
8208                 check_ost=true
8209                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8210                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8211         else
8212                 echo "OSS do not support bulk pages dump upon error"
8213         fi
8214
8215         osc_file_prefix=$($LCTL get_param -n debug_path)
8216         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8217
8218         trap cleanup_77c EXIT
8219
8220         set_checksums 1
8221         # enable bulk pages dump upon error on Client
8222         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8223         # enable bulk pages dump upon error on OSS
8224         $check_ost &&
8225                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8226
8227         # flush Client cache to allow next read to reach OSS
8228         cancel_lru_locks osc
8229
8230         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8231         $LCTL set_param fail_loc=0x80000408
8232         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8233         $LCTL set_param fail_loc=0
8234
8235         rm -f $DIR/$tfile
8236
8237         # check cksum dump on Client
8238         osc_file=$(ls ${osc_file_prefix}*)
8239         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8240         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8241         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8242         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8243         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8244                      cksum)
8245         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8246         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8247                 error "dump content does not match on Client"
8248
8249         $check_ost || skip "No need to check cksum dump on OSS"
8250
8251         # check cksum dump on OSS
8252         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8253         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8254         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8255         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8256         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8257                 error "dump content does not match on OSS"
8258
8259         cleanup_77c
8260 }
8261 run_test 77c "checksum error on client read with debug"
8262
8263 test_77d() { # bug 10889
8264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8265         $GSS && skip_env "could not run with gss"
8266
8267         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8268         $LCTL set_param fail_loc=0x80000409
8269         set_checksums 1
8270         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8271                 error "direct write: rc=$?"
8272         $LCTL set_param fail_loc=0
8273         set_checksums 0
8274
8275         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8276         $LCTL set_param fail_loc=0x80000408
8277         set_checksums 1
8278         cancel_lru_locks osc
8279         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8280                 error "direct read: rc=$?"
8281         $LCTL set_param fail_loc=0
8282         set_checksums 0
8283 }
8284 run_test 77d "checksum error on OST direct write, read"
8285
8286 test_77f() { # bug 10889
8287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8288         $GSS && skip_env "could not run with gss"
8289
8290         set_checksums 1
8291         for algo in $CKSUM_TYPES; do
8292                 cancel_lru_locks osc
8293                 set_checksum_type $algo
8294                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8295                 $LCTL set_param fail_loc=0x409
8296                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8297                         error "direct write succeeded"
8298                 $LCTL set_param fail_loc=0
8299         done
8300         set_checksum_type $ORIG_CSUM_TYPE
8301         set_checksums 0
8302 }
8303 run_test 77f "repeat checksum error on write (expect error)"
8304
8305 test_77g() { # bug 10889
8306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8307         $GSS && skip_env "could not run with gss"
8308         remote_ost_nodsh && skip "remote OST with nodsh"
8309
8310         [ ! -f $F77_TMP ] && setup_f77
8311
8312         local file=$DIR/$tfile
8313         stack_trap "rm -f $file" EXIT
8314
8315         $LFS setstripe -c 1 -i 0 $file
8316         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8317         do_facet ost1 lctl set_param fail_loc=0x8000021a
8318         set_checksums 1
8319         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8320                 error "write error: rc=$?"
8321         do_facet ost1 lctl set_param fail_loc=0
8322         set_checksums 0
8323
8324         cancel_lru_locks osc
8325         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8326         do_facet ost1 lctl set_param fail_loc=0x8000021b
8327         set_checksums 1
8328         cmp $F77_TMP $file || error "file compare failed"
8329         do_facet ost1 lctl set_param fail_loc=0
8330         set_checksums 0
8331 }
8332 run_test 77g "checksum error on OST write, read"
8333
8334 test_77k() { # LU-10906
8335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8336         $GSS && skip_env "could not run with gss"
8337
8338         local cksum_param="osc.$FSNAME*.checksums"
8339         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8340         local checksum
8341         local i
8342
8343         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8344         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
8345         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
8346                 EXIT
8347
8348         for i in 0 1; do
8349                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8350                         error "failed to set checksum=$i on MGS"
8351                 wait_update $HOSTNAME "$get_checksum" $i
8352                 #remount
8353                 echo "remount client, checksum should be $i"
8354                 remount_client $MOUNT || error "failed to remount client"
8355                 checksum=$(eval $get_checksum)
8356                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8357         done
8358         # remove persistent param to avoid races with checksum mountopt below
8359         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8360                 error "failed to delete checksum on MGS"
8361
8362         for opt in "checksum" "nochecksum"; do
8363                 #remount with mount option
8364                 echo "remount client with option $opt, checksum should be $i"
8365                 umount_client $MOUNT || error "failed to umount client"
8366                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8367                         error "failed to mount client with option '$opt'"
8368                 checksum=$(eval $get_checksum)
8369                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8370                 i=$((i - 1))
8371         done
8372
8373         remount_client $MOUNT || error "failed to remount client"
8374 }
8375 run_test 77k "enable/disable checksum correctly"
8376
8377 test_77l() {
8378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8379         $GSS && skip_env "could not run with gss"
8380
8381         set_checksums 1
8382         stack_trap "set_checksums $ORIG_CSUM" EXIT
8383         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8384
8385         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8386
8387         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8388         for algo in $CKSUM_TYPES; do
8389                 set_checksum_type $algo || error "fail to set checksum type $algo"
8390                 osc_algo=$(get_osc_checksum_type OST0000)
8391                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8392
8393                 # no locks, no reqs to let the connection idle
8394                 cancel_lru_locks osc
8395                 lru_resize_disable osc
8396                 wait_osc_import_state client ost1 IDLE
8397
8398                 # ensure ost1 is connected
8399                 stat $DIR/$tfile >/dev/null || error "can't stat"
8400                 wait_osc_import_state client ost1 FULL
8401
8402                 osc_algo=$(get_osc_checksum_type OST0000)
8403                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8404         done
8405         return 0
8406 }
8407 run_test 77l "preferred checksum type is remembered after reconnected"
8408
8409 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8410 rm -f $F77_TMP
8411 unset F77_TMP
8412
8413 cleanup_test_78() {
8414         trap 0
8415         rm -f $DIR/$tfile
8416 }
8417
8418 test_78() { # bug 10901
8419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8420         remote_ost || skip_env "local OST"
8421
8422         NSEQ=5
8423         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8424         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8425         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8426         echo "MemTotal: $MEMTOTAL"
8427
8428         # reserve 256MB of memory for the kernel and other running processes,
8429         # and then take 1/2 of the remaining memory for the read/write buffers.
8430         if [ $MEMTOTAL -gt 512 ] ;then
8431                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8432         else
8433                 # for those poor memory-starved high-end clusters...
8434                 MEMTOTAL=$((MEMTOTAL / 2))
8435         fi
8436         echo "Mem to use for directio: $MEMTOTAL"
8437
8438         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8439         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8440         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8441         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8442                 head -n1)
8443         echo "Smallest OST: $SMALLESTOST"
8444         [[ $SMALLESTOST -lt 10240 ]] &&
8445                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8446
8447         trap cleanup_test_78 EXIT
8448
8449         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8450                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8451
8452         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8453         echo "File size: $F78SIZE"
8454         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8455         for i in $(seq 1 $NSEQ); do
8456                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8457                 echo directIO rdwr round $i of $NSEQ
8458                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8459         done
8460
8461         cleanup_test_78
8462 }
8463 run_test 78 "handle large O_DIRECT writes correctly ============"
8464
8465 test_79() { # bug 12743
8466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8467
8468         wait_delete_completed
8469
8470         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8471         BKFREE=$(calc_osc_kbytes kbytesfree)
8472         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8473
8474         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8475         DFTOTAL=`echo $STRING | cut -d, -f1`
8476         DFUSED=`echo $STRING  | cut -d, -f2`
8477         DFAVAIL=`echo $STRING | cut -d, -f3`
8478         DFFREE=$(($DFTOTAL - $DFUSED))
8479
8480         ALLOWANCE=$((64 * $OSTCOUNT))
8481
8482         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8483            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8484                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8485         fi
8486         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8487            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8488                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8489         fi
8490         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8491            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8492                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8493         fi
8494 }
8495 run_test 79 "df report consistency check ======================="
8496
8497 test_80() { # bug 10718
8498         remote_ost_nodsh && skip "remote OST with nodsh"
8499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8500
8501         # relax strong synchronous semantics for slow backends like ZFS
8502         local soc="obdfilter.*.sync_on_lock_cancel"
8503         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8504         local hosts=
8505         if [ "$soc_old" != "never" ] &&
8506                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8507                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8508                                 facet_active_host $host; done | sort -u)
8509                         do_nodes $hosts lctl set_param $soc=never
8510         fi
8511
8512         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8513         sync; sleep 1; sync
8514         local BEFORE=`date +%s`
8515         cancel_lru_locks osc
8516         local AFTER=`date +%s`
8517         local DIFF=$((AFTER-BEFORE))
8518         if [ $DIFF -gt 1 ] ; then
8519                 error "elapsed for 1M@1T = $DIFF"
8520         fi
8521
8522         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8523
8524         rm -f $DIR/$tfile
8525 }
8526 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8527
8528 test_81a() { # LU-456
8529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8530         remote_ost_nodsh && skip "remote OST with nodsh"
8531
8532         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8533         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8534         do_facet ost1 lctl set_param fail_loc=0x80000228
8535
8536         # write should trigger a retry and success
8537         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8538         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8539         RC=$?
8540         if [ $RC -ne 0 ] ; then
8541                 error "write should success, but failed for $RC"
8542         fi
8543 }
8544 run_test 81a "OST should retry write when get -ENOSPC ==============="
8545
8546 test_81b() { # LU-456
8547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8548         remote_ost_nodsh && skip "remote OST with nodsh"
8549
8550         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8551         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8552         do_facet ost1 lctl set_param fail_loc=0x228
8553
8554         # write should retry several times and return -ENOSPC finally
8555         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8556         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8557         RC=$?
8558         ENOSPC=28
8559         if [ $RC -ne $ENOSPC ] ; then
8560                 error "dd should fail for -ENOSPC, but succeed."
8561         fi
8562 }
8563 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8564
8565 test_82() { # LU-1031
8566         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8567         local gid1=14091995
8568         local gid2=16022000
8569
8570         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8571         local MULTIPID1=$!
8572         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8573         local MULTIPID2=$!
8574         kill -USR1 $MULTIPID2
8575         sleep 2
8576         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8577                 error "First grouplock does not block second one"
8578         else
8579                 echo "Second grouplock blocks first one"
8580         fi
8581         kill -USR1 $MULTIPID1
8582         wait $MULTIPID1
8583         wait $MULTIPID2
8584 }
8585 run_test 82 "Basic grouplock test"
8586
8587 test_99() {
8588         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8589
8590         test_mkdir $DIR/$tdir.cvsroot
8591         chown $RUNAS_ID $DIR/$tdir.cvsroot
8592
8593         cd $TMP
8594         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8595
8596         cd /etc/init.d
8597         # some versions of cvs import exit(1) when asked to import links or
8598         # files they can't read.  ignore those files.
8599         local toignore=$(find . -type l -printf '-I %f\n' -o \
8600                          ! -perm /4 -printf '-I %f\n')
8601         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8602                 $tdir.reposname vtag rtag
8603
8604         cd $DIR
8605         test_mkdir $DIR/$tdir.reposname
8606         chown $RUNAS_ID $DIR/$tdir.reposname
8607         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8608
8609         cd $DIR/$tdir.reposname
8610         $RUNAS touch foo99
8611         $RUNAS cvs add -m 'addmsg' foo99
8612         $RUNAS cvs update
8613         $RUNAS cvs commit -m 'nomsg' foo99
8614         rm -fr $DIR/$tdir.cvsroot
8615 }
8616 run_test 99 "cvs strange file/directory operations"
8617
8618 test_100() {
8619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8620         [[ "$NETTYPE" =~ tcp ]] ||
8621                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8622         remote_ost_nodsh && skip "remote OST with nodsh"
8623         remote_mds_nodsh && skip "remote MDS with nodsh"
8624         remote_servers ||
8625                 skip "useless for local single node setup"
8626
8627         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8628                 [ "$PROT" != "tcp" ] && continue
8629                 RPORT=$(echo $REMOTE | cut -d: -f2)
8630                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8631
8632                 rc=0
8633                 LPORT=`echo $LOCAL | cut -d: -f2`
8634                 if [ $LPORT -ge 1024 ]; then
8635                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8636                         netstat -tna
8637                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8638                 fi
8639         done
8640         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8641 }
8642 run_test 100 "check local port using privileged port ==========="
8643
8644 function get_named_value()
8645 {
8646     local tag
8647
8648     tag=$1
8649     while read ;do
8650         line=$REPLY
8651         case $line in
8652         $tag*)
8653             echo $line | sed "s/^$tag[ ]*//"
8654             break
8655             ;;
8656         esac
8657     done
8658 }
8659
8660 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8661                    awk '/^max_cached_mb/ { print $2 }')
8662
8663 cleanup_101a() {
8664         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8665         trap 0
8666 }
8667
8668 test_101a() {
8669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8670
8671         local s
8672         local discard
8673         local nreads=10000
8674         local cache_limit=32
8675
8676         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8677         trap cleanup_101a EXIT
8678         $LCTL set_param -n llite.*.read_ahead_stats 0
8679         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8680
8681         #
8682         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8683         #
8684         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8685         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8686
8687         discard=0
8688         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8689                 get_named_value 'read but discarded' | cut -d" " -f1); do
8690                         discard=$(($discard + $s))
8691         done
8692         cleanup_101a
8693
8694         $LCTL get_param osc.*-osc*.rpc_stats
8695         $LCTL get_param llite.*.read_ahead_stats
8696
8697         # Discard is generally zero, but sometimes a few random reads line up
8698         # and trigger larger readahead, which is wasted & leads to discards.
8699         if [[ $(($discard)) -gt $nreads ]]; then
8700                 error "too many ($discard) discarded pages"
8701         fi
8702         rm -f $DIR/$tfile || true
8703 }
8704 run_test 101a "check read-ahead for random reads"
8705
8706 setup_test101bc() {
8707         test_mkdir $DIR/$tdir
8708         local ssize=$1
8709         local FILE_LENGTH=$2
8710         STRIPE_OFFSET=0
8711
8712         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8713
8714         local list=$(comma_list $(osts_nodes))
8715         set_osd_param $list '' read_cache_enable 0
8716         set_osd_param $list '' writethrough_cache_enable 0
8717
8718         trap cleanup_test101bc EXIT
8719         # prepare the read-ahead file
8720         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8721
8722         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8723                                 count=$FILE_SIZE_MB 2> /dev/null
8724
8725 }
8726
8727 cleanup_test101bc() {
8728         trap 0
8729         rm -rf $DIR/$tdir
8730         rm -f $DIR/$tfile
8731
8732         local list=$(comma_list $(osts_nodes))
8733         set_osd_param $list '' read_cache_enable 1
8734         set_osd_param $list '' writethrough_cache_enable 1
8735 }
8736
8737 calc_total() {
8738         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8739 }
8740
8741 ra_check_101() {
8742         local READ_SIZE=$1
8743         local STRIPE_SIZE=$2
8744         local FILE_LENGTH=$3
8745         local RA_INC=1048576
8746         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8747         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8748                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8749         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8750                         get_named_value 'read but discarded' |
8751                         cut -d" " -f1 | calc_total)
8752         if [[ $DISCARD -gt $discard_limit ]]; then
8753                 $LCTL get_param llite.*.read_ahead_stats
8754                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8755         else
8756                 echo "Read-ahead success for size ${READ_SIZE}"
8757         fi
8758 }
8759
8760 test_101b() {
8761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8762         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8763
8764         local STRIPE_SIZE=1048576
8765         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8766
8767         if [ $SLOW == "yes" ]; then
8768                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8769         else
8770                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8771         fi
8772
8773         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8774
8775         # prepare the read-ahead file
8776         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8777         cancel_lru_locks osc
8778         for BIDX in 2 4 8 16 32 64 128 256
8779         do
8780                 local BSIZE=$((BIDX*4096))
8781                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8782                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8783                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8784                 $LCTL set_param -n llite.*.read_ahead_stats 0
8785                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8786                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8787                 cancel_lru_locks osc
8788                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8789         done
8790         cleanup_test101bc
8791         true
8792 }
8793 run_test 101b "check stride-io mode read-ahead ================="
8794
8795 test_101c() {
8796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8797
8798         local STRIPE_SIZE=1048576
8799         local FILE_LENGTH=$((STRIPE_SIZE*100))
8800         local nreads=10000
8801         local rsize=65536
8802         local osc_rpc_stats
8803
8804         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8805
8806         cancel_lru_locks osc
8807         $LCTL set_param osc.*.rpc_stats 0
8808         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8809         $LCTL get_param osc.*.rpc_stats
8810         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8811                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8812                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8813                 local size
8814
8815                 if [ $lines -le 20 ]; then
8816                         echo "continue debug"
8817                         continue
8818                 fi
8819                 for size in 1 2 4 8; do
8820                         local rpc=$(echo "$stats" |
8821                                     awk '($1 == "'$size':") {print $2; exit; }')
8822                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8823                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8824                 done
8825                 echo "$osc_rpc_stats check passed!"
8826         done
8827         cleanup_test101bc
8828         true
8829 }
8830 run_test 101c "check stripe_size aligned read-ahead ================="
8831
8832 set_read_ahead() {
8833         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8834         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8835 }
8836
8837 test_101d() {
8838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8839
8840         local file=$DIR/$tfile
8841         local sz_MB=${FILESIZE_101d:-500}
8842         local ra_MB=${READAHEAD_MB:-40}
8843
8844         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8845         [ $free_MB -lt $sz_MB ] &&
8846                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8847
8848         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8849         $LFS setstripe -c -1 $file || error "setstripe failed"
8850
8851         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8852         echo Cancel LRU locks on lustre client to flush the client cache
8853         cancel_lru_locks osc
8854
8855         echo Disable read-ahead
8856         local old_READAHEAD=$(set_read_ahead 0)
8857
8858         echo Reading the test file $file with read-ahead disabled
8859         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8860
8861         echo Cancel LRU locks on lustre client to flush the client cache
8862         cancel_lru_locks osc
8863         echo Enable read-ahead with ${ra_MB}MB
8864         set_read_ahead $ra_MB
8865
8866         echo Reading the test file $file with read-ahead enabled
8867         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8868
8869         echo "read-ahead disabled time read $raOFF"
8870         echo "read-ahead enabled  time read $raON"
8871
8872         set_read_ahead $old_READAHEAD
8873         rm -f $file
8874         wait_delete_completed
8875
8876         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8877                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8878 }
8879 run_test 101d "file read with and without read-ahead enabled"
8880
8881 test_101e() {
8882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8883
8884         local file=$DIR/$tfile
8885         local size_KB=500  #KB
8886         local count=100
8887         local bsize=1024
8888
8889         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8890         local need_KB=$((count * size_KB))
8891         [[ $free_KB -le $need_KB ]] &&
8892                 skip_env "Need free space $need_KB, have $free_KB"
8893
8894         echo "Creating $count ${size_KB}K test files"
8895         for ((i = 0; i < $count; i++)); do
8896                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8897         done
8898
8899         echo "Cancel LRU locks on lustre client to flush the client cache"
8900         cancel_lru_locks $OSC
8901
8902         echo "Reset readahead stats"
8903         $LCTL set_param -n llite.*.read_ahead_stats 0
8904
8905         for ((i = 0; i < $count; i++)); do
8906                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8907         done
8908
8909         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8910                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8911
8912         for ((i = 0; i < $count; i++)); do
8913                 rm -rf $file.$i 2>/dev/null
8914         done
8915
8916         #10000 means 20% reads are missing in readahead
8917         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8918 }
8919 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8920
8921 test_101f() {
8922         which iozone || skip_env "no iozone installed"
8923
8924         local old_debug=$($LCTL get_param debug)
8925         old_debug=${old_debug#*=}
8926         $LCTL set_param debug="reada mmap"
8927
8928         # create a test file
8929         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8930
8931         echo Cancel LRU locks on lustre client to flush the client cache
8932         cancel_lru_locks osc
8933
8934         echo Reset readahead stats
8935         $LCTL set_param -n llite.*.read_ahead_stats 0
8936
8937         echo mmap read the file with small block size
8938         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8939                 > /dev/null 2>&1
8940
8941         echo checking missing pages
8942         $LCTL get_param llite.*.read_ahead_stats
8943         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8944                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8945
8946         $LCTL set_param debug="$old_debug"
8947         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8948         rm -f $DIR/$tfile
8949 }
8950 run_test 101f "check mmap read performance"
8951
8952 test_101g_brw_size_test() {
8953         local mb=$1
8954         local pages=$((mb * 1048576 / PAGE_SIZE))
8955         local file=$DIR/$tfile
8956
8957         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8958                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8959         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8960                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8961                         return 2
8962         done
8963
8964         stack_trap "rm -f $file" EXIT
8965         $LCTL set_param -n osc.*.rpc_stats=0
8966
8967         # 10 RPCs should be enough for the test
8968         local count=10
8969         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8970                 { error "dd write ${mb} MB blocks failed"; return 3; }
8971         cancel_lru_locks osc
8972         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8973                 { error "dd write ${mb} MB blocks failed"; return 4; }
8974
8975         # calculate number of full-sized read and write RPCs
8976         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8977                 sed -n '/pages per rpc/,/^$/p' |
8978                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8979                 END { print reads,writes }'))
8980         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8981                 return 5
8982         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8983                 return 6
8984
8985         return 0
8986 }
8987
8988 test_101g() {
8989         remote_ost_nodsh && skip "remote OST with nodsh"
8990
8991         local rpcs
8992         local osts=$(get_facets OST)
8993         local list=$(comma_list $(osts_nodes))
8994         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8995         local brw_size="obdfilter.*.brw_size"
8996
8997         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8998
8999         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9000
9001         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9002                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9003                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9004            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9005                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9006                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9007
9008                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9009                         suffix="M"
9010
9011                 if [[ $orig_mb -lt 16 ]]; then
9012                         save_lustre_params $osts "$brw_size" > $p
9013                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9014                                 error "set 16MB RPC size failed"
9015
9016                         echo "remount client to enable new RPC size"
9017                         remount_client $MOUNT || error "remount_client failed"
9018                 fi
9019
9020                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9021                 # should be able to set brw_size=12, but no rpc_stats for that
9022                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9023         fi
9024
9025         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9026
9027         if [[ $orig_mb -lt 16 ]]; then
9028                 restore_lustre_params < $p
9029                 remount_client $MOUNT || error "remount_client restore failed"
9030         fi
9031
9032         rm -f $p $DIR/$tfile
9033 }
9034 run_test 101g "Big bulk(4/16 MiB) readahead"
9035
9036 test_101h() {
9037         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9038
9039         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9040                 error "dd 70M file failed"
9041         echo Cancel LRU locks on lustre client to flush the client cache
9042         cancel_lru_locks osc
9043
9044         echo "Reset readahead stats"
9045         $LCTL set_param -n llite.*.read_ahead_stats 0
9046
9047         echo "Read 10M of data but cross 64M bundary"
9048         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9049         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9050                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9051         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9052         rm -f $p $DIR/$tfile
9053 }
9054 run_test 101h "Readahead should cover current read window"
9055
9056 setup_test102() {
9057         test_mkdir $DIR/$tdir
9058         chown $RUNAS_ID $DIR/$tdir
9059         STRIPE_SIZE=65536
9060         STRIPE_OFFSET=1
9061         STRIPE_COUNT=$OSTCOUNT
9062         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9063
9064         trap cleanup_test102 EXIT
9065         cd $DIR
9066         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9067         cd $DIR/$tdir
9068         for num in 1 2 3 4; do
9069                 for count in $(seq 1 $STRIPE_COUNT); do
9070                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9071                                 local size=`expr $STRIPE_SIZE \* $num`
9072                                 local file=file"$num-$idx-$count"
9073                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9074                         done
9075                 done
9076         done
9077
9078         cd $DIR
9079         $1 tar cf $TMP/f102.tar $tdir --xattrs
9080 }
9081
9082 cleanup_test102() {
9083         trap 0
9084         rm -f $TMP/f102.tar
9085         rm -rf $DIR/d0.sanity/d102
9086 }
9087
9088 test_102a() {
9089         [ "$UID" != 0 ] && skip "must run as root"
9090         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9091                 skip_env "must have user_xattr"
9092
9093         [ -z "$(which setfattr 2>/dev/null)" ] &&
9094                 skip_env "could not find setfattr"
9095
9096         local testfile=$DIR/$tfile
9097
9098         touch $testfile
9099         echo "set/get xattr..."
9100         setfattr -n trusted.name1 -v value1 $testfile ||
9101                 error "setfattr -n trusted.name1=value1 $testfile failed"
9102         getfattr -n trusted.name1 $testfile 2> /dev/null |
9103           grep "trusted.name1=.value1" ||
9104                 error "$testfile missing trusted.name1=value1"
9105
9106         setfattr -n user.author1 -v author1 $testfile ||
9107                 error "setfattr -n user.author1=author1 $testfile failed"
9108         getfattr -n user.author1 $testfile 2> /dev/null |
9109           grep "user.author1=.author1" ||
9110                 error "$testfile missing trusted.author1=author1"
9111
9112         echo "listxattr..."
9113         setfattr -n trusted.name2 -v value2 $testfile ||
9114                 error "$testfile unable to set trusted.name2"
9115         setfattr -n trusted.name3 -v value3 $testfile ||
9116                 error "$testfile unable to set trusted.name3"
9117         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9118             grep "trusted.name" | wc -l) -eq 3 ] ||
9119                 error "$testfile missing 3 trusted.name xattrs"
9120
9121         setfattr -n user.author2 -v author2 $testfile ||
9122                 error "$testfile unable to set user.author2"
9123         setfattr -n user.author3 -v author3 $testfile ||
9124                 error "$testfile unable to set user.author3"
9125         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9126             grep "user.author" | wc -l) -eq 3 ] ||
9127                 error "$testfile missing 3 user.author xattrs"
9128
9129         echo "remove xattr..."
9130         setfattr -x trusted.name1 $testfile ||
9131                 error "$testfile error deleting trusted.name1"
9132         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9133                 error "$testfile did not delete trusted.name1 xattr"
9134
9135         setfattr -x user.author1 $testfile ||
9136                 error "$testfile error deleting user.author1"
9137         echo "set lustre special xattr ..."
9138         $LFS setstripe -c1 $testfile
9139         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9140                 awk -F "=" '/trusted.lov/ { print $2 }' )
9141         setfattr -n "trusted.lov" -v $lovea $testfile ||
9142                 error "$testfile doesn't ignore setting trusted.lov again"
9143         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9144                 error "$testfile allow setting invalid trusted.lov"
9145         rm -f $testfile
9146 }
9147 run_test 102a "user xattr test =================================="
9148
9149 test_102b() {
9150         [ -z "$(which setfattr 2>/dev/null)" ] &&
9151                 skip_env "could not find setfattr"
9152         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9153
9154         # b10930: get/set/list trusted.lov xattr
9155         echo "get/set/list trusted.lov xattr ..."
9156         local testfile=$DIR/$tfile
9157         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9158                 error "setstripe failed"
9159         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
9160                 error "getstripe failed"
9161         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
9162                 error "can't get trusted.lov from $testfile"
9163
9164         local testfile2=${testfile}2
9165         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
9166                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
9167
9168         $MCREATE $testfile2
9169         setfattr -n trusted.lov -v $value $testfile2
9170         local stripe_size=$($LFS getstripe -S $testfile2)
9171         local stripe_count=$($LFS getstripe -c $testfile2)
9172         [[ $stripe_size -eq 65536 ]] ||
9173                 error "stripe size $stripe_size != 65536"
9174         [[ $stripe_count -eq $STRIPECOUNT ]] ||
9175                 error "stripe count $stripe_count != $STRIPECOUNT"
9176         rm -f $DIR/$tfile
9177 }
9178 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
9179
9180 test_102c() {
9181         [ -z "$(which setfattr 2>/dev/null)" ] &&
9182                 skip_env "could not find setfattr"
9183         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9184
9185         # b10930: get/set/list lustre.lov xattr
9186         echo "get/set/list lustre.lov xattr ..."
9187         test_mkdir $DIR/$tdir
9188         chown $RUNAS_ID $DIR/$tdir
9189         local testfile=$DIR/$tdir/$tfile
9190         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9191                 error "setstripe failed"
9192         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9193                 error "getstripe failed"
9194         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9195         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9196
9197         local testfile2=${testfile}2
9198         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9199                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9200
9201         $RUNAS $MCREATE $testfile2
9202         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9203         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9204         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9205         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9206         [ $stripe_count -eq $STRIPECOUNT ] ||
9207                 error "stripe count $stripe_count != $STRIPECOUNT"
9208 }
9209 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9210
9211 compare_stripe_info1() {
9212         local stripe_index_all_zero=true
9213
9214         for num in 1 2 3 4; do
9215                 for count in $(seq 1 $STRIPE_COUNT); do
9216                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9217                                 local size=$((STRIPE_SIZE * num))
9218                                 local file=file"$num-$offset-$count"
9219                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9220                                 [[ $stripe_size -ne $size ]] &&
9221                                     error "$file: size $stripe_size != $size"
9222                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9223                                 # allow fewer stripes to be created, ORI-601
9224                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9225                                     error "$file: count $stripe_count != $count"
9226                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9227                                 [[ $stripe_index -ne 0 ]] &&
9228                                         stripe_index_all_zero=false
9229                         done
9230                 done
9231         done
9232         $stripe_index_all_zero &&
9233                 error "all files are being extracted starting from OST index 0"
9234         return 0
9235 }
9236
9237 have_xattrs_include() {
9238         tar --help | grep -q xattrs-include &&
9239                 echo --xattrs-include="lustre.*"
9240 }
9241
9242 test_102d() {
9243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9244         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9245
9246         XINC=$(have_xattrs_include)
9247         setup_test102
9248         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9249         cd $DIR/$tdir/$tdir
9250         compare_stripe_info1
9251 }
9252 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9253
9254 test_102f() {
9255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9256         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9257
9258         XINC=$(have_xattrs_include)
9259         setup_test102
9260         test_mkdir $DIR/$tdir.restore
9261         cd $DIR
9262         tar cf - --xattrs $tdir | tar xf - \
9263                 -C $DIR/$tdir.restore --xattrs $XINC
9264         cd $DIR/$tdir.restore/$tdir
9265         compare_stripe_info1
9266 }
9267 run_test 102f "tar copy files, not keep osts"
9268
9269 grow_xattr() {
9270         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9271                 skip "must have user_xattr"
9272         [ -z "$(which setfattr 2>/dev/null)" ] &&
9273                 skip_env "could not find setfattr"
9274         [ -z "$(which getfattr 2>/dev/null)" ] &&
9275                 skip_env "could not find getfattr"
9276
9277         local xsize=${1:-1024}  # in bytes
9278         local file=$DIR/$tfile
9279         local value="$(generate_string $xsize)"
9280         local xbig=trusted.big
9281         local toobig=$2
9282
9283         touch $file
9284         log "save $xbig on $file"
9285         if [ -z "$toobig" ]
9286         then
9287                 setfattr -n $xbig -v $value $file ||
9288                         error "saving $xbig on $file failed"
9289         else
9290                 setfattr -n $xbig -v $value $file &&
9291                         error "saving $xbig on $file succeeded"
9292                 return 0
9293         fi
9294
9295         local orig=$(get_xattr_value $xbig $file)
9296         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9297
9298         local xsml=trusted.sml
9299         log "save $xsml on $file"
9300         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9301
9302         local new=$(get_xattr_value $xbig $file)
9303         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9304
9305         log "grow $xsml on $file"
9306         setfattr -n $xsml -v "$value" $file ||
9307                 error "growing $xsml on $file failed"
9308
9309         new=$(get_xattr_value $xbig $file)
9310         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9311         log "$xbig still valid after growing $xsml"
9312
9313         rm -f $file
9314 }
9315
9316 test_102h() { # bug 15777
9317         grow_xattr 1024
9318 }
9319 run_test 102h "grow xattr from inside inode to external block"
9320
9321 test_102ha() {
9322         large_xattr_enabled || skip_env "ea_inode feature disabled"
9323
9324         echo "setting xattr of max xattr size: $(max_xattr_size)"
9325         grow_xattr $(max_xattr_size)
9326
9327         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9328         echo "This should fail:"
9329         grow_xattr $(($(max_xattr_size) + 10)) 1
9330 }
9331 run_test 102ha "grow xattr from inside inode to external inode"
9332
9333 test_102i() { # bug 17038
9334         [ -z "$(which getfattr 2>/dev/null)" ] &&
9335                 skip "could not find getfattr"
9336
9337         touch $DIR/$tfile
9338         ln -s $DIR/$tfile $DIR/${tfile}link
9339         getfattr -n trusted.lov $DIR/$tfile ||
9340                 error "lgetxattr on $DIR/$tfile failed"
9341         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9342                 grep -i "no such attr" ||
9343                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9344         rm -f $DIR/$tfile $DIR/${tfile}link
9345 }
9346 run_test 102i "lgetxattr test on symbolic link ============"
9347
9348 test_102j() {
9349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9350         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9351
9352         XINC=$(have_xattrs_include)
9353         setup_test102 "$RUNAS"
9354         chown $RUNAS_ID $DIR/$tdir
9355         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9356         cd $DIR/$tdir/$tdir
9357         compare_stripe_info1 "$RUNAS"
9358 }
9359 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9360
9361 test_102k() {
9362         [ -z "$(which setfattr 2>/dev/null)" ] &&
9363                 skip "could not find setfattr"
9364
9365         touch $DIR/$tfile
9366         # b22187 just check that does not crash for regular file.
9367         setfattr -n trusted.lov $DIR/$tfile
9368         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9369         local test_kdir=$DIR/$tdir
9370         test_mkdir $test_kdir
9371         local default_size=$($LFS getstripe -S $test_kdir)
9372         local default_count=$($LFS getstripe -c $test_kdir)
9373         local default_offset=$($LFS getstripe -i $test_kdir)
9374         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9375                 error 'dir setstripe failed'
9376         setfattr -n trusted.lov $test_kdir
9377         local stripe_size=$($LFS getstripe -S $test_kdir)
9378         local stripe_count=$($LFS getstripe -c $test_kdir)
9379         local stripe_offset=$($LFS getstripe -i $test_kdir)
9380         [ $stripe_size -eq $default_size ] ||
9381                 error "stripe size $stripe_size != $default_size"
9382         [ $stripe_count -eq $default_count ] ||
9383                 error "stripe count $stripe_count != $default_count"
9384         [ $stripe_offset -eq $default_offset ] ||
9385                 error "stripe offset $stripe_offset != $default_offset"
9386         rm -rf $DIR/$tfile $test_kdir
9387 }
9388 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
9389
9390 test_102l() {
9391         [ -z "$(which getfattr 2>/dev/null)" ] &&
9392                 skip "could not find getfattr"
9393
9394         # LU-532 trusted. xattr is invisible to non-root
9395         local testfile=$DIR/$tfile
9396
9397         touch $testfile
9398
9399         echo "listxattr as user..."
9400         chown $RUNAS_ID $testfile
9401         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
9402             grep -q "trusted" &&
9403                 error "$testfile trusted xattrs are user visible"
9404
9405         return 0;
9406 }
9407 run_test 102l "listxattr size test =================================="
9408
9409 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9410         local path=$DIR/$tfile
9411         touch $path
9412
9413         listxattr_size_check $path || error "listattr_size_check $path failed"
9414 }
9415 run_test 102m "Ensure listxattr fails on small bufffer ========"
9416
9417 cleanup_test102
9418
9419 getxattr() { # getxattr path name
9420         # Return the base64 encoding of the value of xattr name on path.
9421         local path=$1
9422         local name=$2
9423
9424         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9425         # file: $path
9426         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9427         #
9428         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9429
9430         getfattr --absolute-names --encoding=base64 --name=$name $path |
9431                 awk -F= -v name=$name '$1 == name {
9432                         print substr($0, index($0, "=") + 1);
9433         }'
9434 }
9435
9436 test_102n() { # LU-4101 mdt: protect internal xattrs
9437         [ -z "$(which setfattr 2>/dev/null)" ] &&
9438                 skip "could not find setfattr"
9439         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9440         then
9441                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9442         fi
9443
9444         local file0=$DIR/$tfile.0
9445         local file1=$DIR/$tfile.1
9446         local xattr0=$TMP/$tfile.0
9447         local xattr1=$TMP/$tfile.1
9448         local namelist="lov lma lmv link fid version som hsm"
9449         local name
9450         local value
9451
9452         rm -rf $file0 $file1 $xattr0 $xattr1
9453         touch $file0 $file1
9454
9455         # Get 'before' xattrs of $file1.
9456         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9457
9458         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9459                 namelist+=" lfsck_namespace"
9460         for name in $namelist; do
9461                 # Try to copy xattr from $file0 to $file1.
9462                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9463
9464                 setfattr --name=trusted.$name --value="$value" $file1 ||
9465                         error "setxattr 'trusted.$name' failed"
9466
9467                 # Try to set a garbage xattr.
9468                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9469
9470                 if [[ x$name == "xlov" ]]; then
9471                         setfattr --name=trusted.lov --value="$value" $file1 &&
9472                         error "setxattr invalid 'trusted.lov' success"
9473                 else
9474                         setfattr --name=trusted.$name --value="$value" $file1 ||
9475                                 error "setxattr invalid 'trusted.$name' failed"
9476                 fi
9477
9478                 # Try to remove the xattr from $file1. We don't care if this
9479                 # appears to succeed or fail, we just don't want there to be
9480                 # any changes or crashes.
9481                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9482         done
9483
9484         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9485         then
9486                 name="lfsck_ns"
9487                 # Try to copy xattr from $file0 to $file1.
9488                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9489
9490                 setfattr --name=trusted.$name --value="$value" $file1 ||
9491                         error "setxattr 'trusted.$name' failed"
9492
9493                 # Try to set a garbage xattr.
9494                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9495
9496                 setfattr --name=trusted.$name --value="$value" $file1 ||
9497                         error "setxattr 'trusted.$name' failed"
9498
9499                 # Try to remove the xattr from $file1. We don't care if this
9500                 # appears to succeed or fail, we just don't want there to be
9501                 # any changes or crashes.
9502                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9503         fi
9504
9505         # Get 'after' xattrs of file1.
9506         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9507
9508         if ! diff $xattr0 $xattr1; then
9509                 error "before and after xattrs of '$file1' differ"
9510         fi
9511
9512         rm -rf $file0 $file1 $xattr0 $xattr1
9513
9514         return 0
9515 }
9516 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9517
9518 test_102p() { # LU-4703 setxattr did not check ownership
9519         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9520                 skip "MDS needs to be at least 2.5.56"
9521
9522         local testfile=$DIR/$tfile
9523
9524         touch $testfile
9525
9526         echo "setfacl as user..."
9527         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9528         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9529
9530         echo "setfattr as user..."
9531         setfacl -m "u:$RUNAS_ID:---" $testfile
9532         $RUNAS setfattr -x system.posix_acl_access $testfile
9533         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9534 }
9535 run_test 102p "check setxattr(2) correctly fails without permission"
9536
9537 test_102q() {
9538         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9539                 skip "MDS needs to be at least 2.6.92"
9540
9541         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9542 }
9543 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9544
9545 test_102r() {
9546         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9547                 skip "MDS needs to be at least 2.6.93"
9548
9549         touch $DIR/$tfile || error "touch"
9550         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9551         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9552         rm $DIR/$tfile || error "rm"
9553
9554         #normal directory
9555         mkdir -p $DIR/$tdir || error "mkdir"
9556         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9557         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9558         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9559                 error "$testfile error deleting user.author1"
9560         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9561                 grep "user.$(basename $tdir)" &&
9562                 error "$tdir did not delete user.$(basename $tdir)"
9563         rmdir $DIR/$tdir || error "rmdir"
9564
9565         #striped directory
9566         test_mkdir $DIR/$tdir
9567         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9568         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9569         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9570                 error "$testfile error deleting user.author1"
9571         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9572                 grep "user.$(basename $tdir)" &&
9573                 error "$tdir did not delete user.$(basename $tdir)"
9574         rmdir $DIR/$tdir || error "rm striped dir"
9575 }
9576 run_test 102r "set EAs with empty values"
9577
9578 test_102s() {
9579         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9580                 skip "MDS needs to be at least 2.11.52"
9581
9582         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9583
9584         save_lustre_params client "llite.*.xattr_cache" > $save
9585
9586         for cache in 0 1; do
9587                 lctl set_param llite.*.xattr_cache=$cache
9588
9589                 rm -f $DIR/$tfile
9590                 touch $DIR/$tfile || error "touch"
9591                 for prefix in lustre security system trusted user; do
9592                         # Note getxattr() may fail with 'Operation not
9593                         # supported' or 'No such attribute' depending
9594                         # on prefix and cache.
9595                         getfattr -n $prefix.n102s $DIR/$tfile &&
9596                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9597                 done
9598         done
9599
9600         restore_lustre_params < $save
9601 }
9602 run_test 102s "getting nonexistent xattrs should fail"
9603
9604 test_102t() {
9605         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9606                 skip "MDS needs to be at least 2.11.52"
9607
9608         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9609
9610         save_lustre_params client "llite.*.xattr_cache" > $save
9611
9612         for cache in 0 1; do
9613                 lctl set_param llite.*.xattr_cache=$cache
9614
9615                 for buf_size in 0 256; do
9616                         rm -f $DIR/$tfile
9617                         touch $DIR/$tfile || error "touch"
9618                         setfattr -n user.multiop $DIR/$tfile
9619                         $MULTIOP $DIR/$tfile oa$buf_size ||
9620                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9621                 done
9622         done
9623
9624         restore_lustre_params < $save
9625 }
9626 run_test 102t "zero length xattr values handled correctly"
9627
9628 run_acl_subtest()
9629 {
9630     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9631     return $?
9632 }
9633
9634 test_103a() {
9635         [ "$UID" != 0 ] && skip "must run as root"
9636         $GSS && skip_env "could not run under gss"
9637         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9638                 skip_env "must have acl enabled"
9639         [ -z "$(which setfacl 2>/dev/null)" ] &&
9640                 skip_env "could not find setfacl"
9641         remote_mds_nodsh && skip "remote MDS with nodsh"
9642
9643         gpasswd -a daemon bin                           # LU-5641
9644         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9645
9646         declare -a identity_old
9647
9648         for num in $(seq $MDSCOUNT); do
9649                 switch_identity $num true || identity_old[$num]=$?
9650         done
9651
9652         SAVE_UMASK=$(umask)
9653         umask 0022
9654         mkdir -p $DIR/$tdir
9655         cd $DIR/$tdir
9656
9657         echo "performing cp ..."
9658         run_acl_subtest cp || error "run_acl_subtest cp failed"
9659         echo "performing getfacl-noacl..."
9660         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9661         echo "performing misc..."
9662         run_acl_subtest misc || error  "misc test failed"
9663         echo "performing permissions..."
9664         run_acl_subtest permissions || error "permissions failed"
9665         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9666         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9667                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9668                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9669         then
9670                 echo "performing permissions xattr..."
9671                 run_acl_subtest permissions_xattr ||
9672                         error "permissions_xattr failed"
9673         fi
9674         echo "performing setfacl..."
9675         run_acl_subtest setfacl || error  "setfacl test failed"
9676
9677         # inheritance test got from HP
9678         echo "performing inheritance..."
9679         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9680         chmod +x make-tree || error "chmod +x failed"
9681         run_acl_subtest inheritance || error "inheritance test failed"
9682         rm -f make-tree
9683
9684         echo "LU-974 ignore umask when acl is enabled..."
9685         run_acl_subtest 974 || error "LU-974 umask test failed"
9686         if [ $MDSCOUNT -ge 2 ]; then
9687                 run_acl_subtest 974_remote ||
9688                         error "LU-974 umask test failed under remote dir"
9689         fi
9690
9691         echo "LU-2561 newly created file is same size as directory..."
9692         if [ "$mds1_FSTYPE" != "zfs" ]; then
9693                 run_acl_subtest 2561 || error "LU-2561 test failed"
9694         else
9695                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9696         fi
9697
9698         run_acl_subtest 4924 || error "LU-4924 test failed"
9699
9700         cd $SAVE_PWD
9701         umask $SAVE_UMASK
9702
9703         for num in $(seq $MDSCOUNT); do
9704                 if [ "${identity_old[$num]}" = 1 ]; then
9705                         switch_identity $num false || identity_old[$num]=$?
9706                 fi
9707         done
9708 }
9709 run_test 103a "acl test"
9710
9711 test_103b() {
9712         declare -a pids
9713         local U
9714
9715         for U in {0..511}; do
9716                 {
9717                 local O=$(printf "%04o" $U)
9718
9719                 umask $(printf "%04o" $((511 ^ $O)))
9720                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9721                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9722
9723                 (( $S == ($O & 0666) )) ||
9724                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9725
9726                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9727                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9728                 (( $S == ($O & 0666) )) ||
9729                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9730
9731                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9732                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9733                 (( $S == ($O & 0666) )) ||
9734                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9735                 rm -f $DIR/$tfile.[smp]$0
9736                 } &
9737                 local pid=$!
9738
9739                 # limit the concurrently running threads to 64. LU-11878
9740                 local idx=$((U % 64))
9741                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9742                 pids[idx]=$pid
9743         done
9744         wait
9745 }
9746 run_test 103b "umask lfs setstripe"
9747
9748 test_103c() {
9749         mkdir -p $DIR/$tdir
9750         cp -rp $DIR/$tdir $DIR/$tdir.bak
9751
9752         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9753                 error "$DIR/$tdir shouldn't contain default ACL"
9754         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9755                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9756         true
9757 }
9758 run_test 103c "'cp -rp' won't set empty acl"
9759
9760 test_104a() {
9761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9762
9763         touch $DIR/$tfile
9764         lfs df || error "lfs df failed"
9765         lfs df -ih || error "lfs df -ih failed"
9766         lfs df -h $DIR || error "lfs df -h $DIR failed"
9767         lfs df -i $DIR || error "lfs df -i $DIR failed"
9768         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9769         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9770
9771         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9772         lctl --device %$OSC deactivate
9773         lfs df || error "lfs df with deactivated OSC failed"
9774         lctl --device %$OSC activate
9775         # wait the osc back to normal
9776         wait_osc_import_ready client ost
9777
9778         lfs df || error "lfs df with reactivated OSC failed"
9779         rm -f $DIR/$tfile
9780 }
9781 run_test 104a "lfs df [-ih] [path] test ========================="
9782
9783 test_104b() {
9784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9785         [ $RUNAS_ID -eq $UID ] &&
9786                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9787
9788         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9789                         grep "Permission denied" | wc -l)))
9790         if [ $denied_cnt -ne 0 ]; then
9791                 error "lfs check servers test failed"
9792         fi
9793 }
9794 run_test 104b "$RUNAS lfs check servers test ===================="
9795
9796 test_105a() {
9797         # doesn't work on 2.4 kernels
9798         touch $DIR/$tfile
9799         if $(flock_is_enabled); then
9800                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9801         else
9802                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9803         fi
9804         rm -f $DIR/$tfile
9805 }
9806 run_test 105a "flock when mounted without -o flock test ========"
9807
9808 test_105b() {
9809         touch $DIR/$tfile
9810         if $(flock_is_enabled); then
9811                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9812         else
9813                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9814         fi
9815         rm -f $DIR/$tfile
9816 }
9817 run_test 105b "fcntl when mounted without -o flock test ========"
9818
9819 test_105c() {
9820         touch $DIR/$tfile
9821         if $(flock_is_enabled); then
9822                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9823         else
9824                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9825         fi
9826         rm -f $DIR/$tfile
9827 }
9828 run_test 105c "lockf when mounted without -o flock test"
9829
9830 test_105d() { # bug 15924
9831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9832
9833         test_mkdir $DIR/$tdir
9834         flock_is_enabled || skip_env "mount w/o flock enabled"
9835         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9836         $LCTL set_param fail_loc=0x80000315
9837         flocks_test 2 $DIR/$tdir
9838 }
9839 run_test 105d "flock race (should not freeze) ========"
9840
9841 test_105e() { # bug 22660 && 22040
9842         flock_is_enabled || skip_env "mount w/o flock enabled"
9843
9844         touch $DIR/$tfile
9845         flocks_test 3 $DIR/$tfile
9846 }
9847 run_test 105e "Two conflicting flocks from same process"
9848
9849 test_106() { #bug 10921
9850         test_mkdir $DIR/$tdir
9851         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9852         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9853 }
9854 run_test 106 "attempt exec of dir followed by chown of that dir"
9855
9856 test_107() {
9857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9858
9859         CDIR=`pwd`
9860         local file=core
9861
9862         cd $DIR
9863         rm -f $file
9864
9865         local save_pattern=$(sysctl -n kernel.core_pattern)
9866         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9867         sysctl -w kernel.core_pattern=$file
9868         sysctl -w kernel.core_uses_pid=0
9869
9870         ulimit -c unlimited
9871         sleep 60 &
9872         SLEEPPID=$!
9873
9874         sleep 1
9875
9876         kill -s 11 $SLEEPPID
9877         wait $SLEEPPID
9878         if [ -e $file ]; then
9879                 size=`stat -c%s $file`
9880                 [ $size -eq 0 ] && error "Fail to create core file $file"
9881         else
9882                 error "Fail to create core file $file"
9883         fi
9884         rm -f $file
9885         sysctl -w kernel.core_pattern=$save_pattern
9886         sysctl -w kernel.core_uses_pid=$save_uses_pid
9887         cd $CDIR
9888 }
9889 run_test 107 "Coredump on SIG"
9890
9891 test_110() {
9892         test_mkdir $DIR/$tdir
9893         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9894         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9895                 error "mkdir with 256 char should fail, but did not"
9896         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9897                 error "create with 255 char failed"
9898         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9899                 error "create with 256 char should fail, but did not"
9900
9901         ls -l $DIR/$tdir
9902         rm -rf $DIR/$tdir
9903 }
9904 run_test 110 "filename length checking"
9905
9906 #
9907 # Purpose: To verify dynamic thread (OSS) creation.
9908 #
9909 test_115() {
9910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9911         remote_ost_nodsh && skip "remote OST with nodsh"
9912
9913         # Lustre does not stop service threads once they are started.
9914         # Reset number of running threads to default.
9915         stopall
9916         setupall
9917
9918         local OSTIO_pre
9919         local save_params="$TMP/sanity-$TESTNAME.parameters"
9920
9921         # Get ll_ost_io count before I/O
9922         OSTIO_pre=$(do_facet ost1 \
9923                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9924         # Exit if lustre is not running (ll_ost_io not running).
9925         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9926
9927         echo "Starting with $OSTIO_pre threads"
9928         local thread_max=$((OSTIO_pre * 2))
9929         local rpc_in_flight=$((thread_max * 2))
9930         # Number of I/O Process proposed to be started.
9931         local nfiles
9932         local facets=$(get_facets OST)
9933
9934         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9935         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9936
9937         # Set in_flight to $rpc_in_flight
9938         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9939                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9940         nfiles=${rpc_in_flight}
9941         # Set ost thread_max to $thread_max
9942         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9943
9944         # 5 Minutes should be sufficient for max number of OSS
9945         # threads(thread_max) to be created.
9946         local timeout=300
9947
9948         # Start I/O.
9949         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9950         test_mkdir $DIR/$tdir
9951         for i in $(seq $nfiles); do
9952                 local file=$DIR/$tdir/${tfile}-$i
9953                 $LFS setstripe -c -1 -i 0 $file
9954                 ($WTL $file $timeout)&
9955         done
9956
9957         # I/O Started - Wait for thread_started to reach thread_max or report
9958         # error if thread_started is more than thread_max.
9959         echo "Waiting for thread_started to reach thread_max"
9960         local thread_started=0
9961         local end_time=$((SECONDS + timeout))
9962
9963         while [ $SECONDS -le $end_time ] ; do
9964                 echo -n "."
9965                 # Get ost i/o thread_started count.
9966                 thread_started=$(do_facet ost1 \
9967                         "$LCTL get_param \
9968                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9969                 # Break out if thread_started is equal/greater than thread_max
9970                 if [[ $thread_started -ge $thread_max ]]; then
9971                         echo ll_ost_io thread_started $thread_started, \
9972                                 equal/greater than thread_max $thread_max
9973                         break
9974                 fi
9975                 sleep 1
9976         done
9977
9978         # Cleanup - We have the numbers, Kill i/o jobs if running.
9979         jobcount=($(jobs -p))
9980         for i in $(seq 0 $((${#jobcount[@]}-1)))
9981         do
9982                 kill -9 ${jobcount[$i]}
9983                 if [ $? -ne 0 ] ; then
9984                         echo Warning: \
9985                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9986                 fi
9987         done
9988
9989         # Cleanup files left by WTL binary.
9990         for i in $(seq $nfiles); do
9991                 local file=$DIR/$tdir/${tfile}-$i
9992                 rm -rf $file
9993                 if [ $? -ne 0 ] ; then
9994                         echo "Warning: Failed to delete file $file"
9995                 fi
9996         done
9997
9998         restore_lustre_params <$save_params
9999         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10000
10001         # Error out if no new thread has started or Thread started is greater
10002         # than thread max.
10003         if [[ $thread_started -le $OSTIO_pre ||
10004                         $thread_started -gt $thread_max ]]; then
10005                 error "ll_ost_io: thread_started $thread_started" \
10006                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10007                       "No new thread started or thread started greater " \
10008                       "than thread_max."
10009         fi
10010 }
10011 run_test 115 "verify dynamic thread creation===================="
10012
10013 free_min_max () {
10014         wait_delete_completed
10015         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10016         echo "OST kbytes available: ${AVAIL[@]}"
10017         MAXV=${AVAIL[0]}
10018         MAXI=0
10019         MINV=${AVAIL[0]}
10020         MINI=0
10021         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10022                 #echo OST $i: ${AVAIL[i]}kb
10023                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10024                         MAXV=${AVAIL[i]}
10025                         MAXI=$i
10026                 fi
10027                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10028                         MINV=${AVAIL[i]}
10029                         MINI=$i
10030                 fi
10031         done
10032         echo "Min free space: OST $MINI: $MINV"
10033         echo "Max free space: OST $MAXI: $MAXV"
10034 }
10035
10036 test_116a() { # was previously test_116()
10037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10038         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10039         remote_mds_nodsh && skip "remote MDS with nodsh"
10040
10041         echo -n "Free space priority "
10042         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10043                 head -n1
10044         declare -a AVAIL
10045         free_min_max
10046
10047         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10048         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10049         trap simple_cleanup_common EXIT
10050
10051         # Check if we need to generate uneven OSTs
10052         test_mkdir -p $DIR/$tdir/OST${MINI}
10053         local FILL=$((MINV / 4))
10054         local DIFF=$((MAXV - MINV))
10055         local DIFF2=$((DIFF * 100 / MINV))
10056
10057         local threshold=$(do_facet $SINGLEMDS \
10058                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10059         threshold=${threshold%%%}
10060         echo -n "Check for uneven OSTs: "
10061         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10062
10063         if [[ $DIFF2 -gt $threshold ]]; then
10064                 echo "ok"
10065                 echo "Don't need to fill OST$MINI"
10066         else
10067                 # generate uneven OSTs. Write 2% over the QOS threshold value
10068                 echo "no"
10069                 DIFF=$((threshold - DIFF2 + 2))
10070                 DIFF2=$((MINV * DIFF / 100))
10071                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10072                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10073                         error "setstripe failed"
10074                 DIFF=$((DIFF2 / 2048))
10075                 i=0
10076                 while [ $i -lt $DIFF ]; do
10077                         i=$((i + 1))
10078                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10079                                 bs=2M count=1 2>/dev/null
10080                         echo -n .
10081                 done
10082                 echo .
10083                 sync
10084                 sleep_maxage
10085                 free_min_max
10086         fi
10087
10088         DIFF=$((MAXV - MINV))
10089         DIFF2=$((DIFF * 100 / MINV))
10090         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10091         if [ $DIFF2 -gt $threshold ]; then
10092                 echo "ok"
10093         else
10094                 echo "failed - QOS mode won't be used"
10095                 simple_cleanup_common
10096                 skip "QOS imbalance criteria not met"
10097         fi
10098
10099         MINI1=$MINI
10100         MINV1=$MINV
10101         MAXI1=$MAXI
10102         MAXV1=$MAXV
10103
10104         # now fill using QOS
10105         $LFS setstripe -c 1 $DIR/$tdir
10106         FILL=$((FILL / 200))
10107         if [ $FILL -gt 600 ]; then
10108                 FILL=600
10109         fi
10110         echo "writing $FILL files to QOS-assigned OSTs"
10111         i=0
10112         while [ $i -lt $FILL ]; do
10113                 i=$((i + 1))
10114                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10115                         count=1 2>/dev/null
10116                 echo -n .
10117         done
10118         echo "wrote $i 200k files"
10119         sync
10120         sleep_maxage
10121
10122         echo "Note: free space may not be updated, so measurements might be off"
10123         free_min_max
10124         DIFF2=$((MAXV - MINV))
10125         echo "free space delta: orig $DIFF final $DIFF2"
10126         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10127         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10128         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10129         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10130         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10131         if [[ $DIFF -gt 0 ]]; then
10132                 FILL=$((DIFF2 * 100 / DIFF - 100))
10133                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10134         fi
10135
10136         # Figure out which files were written where
10137         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10138                awk '/'$MINI1': / {print $2; exit}')
10139         echo $UUID
10140         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10141         echo "$MINC files created on smaller OST $MINI1"
10142         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10143                awk '/'$MAXI1': / {print $2; exit}')
10144         echo $UUID
10145         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10146         echo "$MAXC files created on larger OST $MAXI1"
10147         if [[ $MINC -gt 0 ]]; then
10148                 FILL=$((MAXC * 100 / MINC - 100))
10149                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10150         fi
10151         [[ $MAXC -gt $MINC ]] ||
10152                 error_ignore LU-9 "stripe QOS didn't balance free space"
10153         simple_cleanup_common
10154 }
10155 run_test 116a "stripe QOS: free space balance ==================="
10156
10157 test_116b() { # LU-2093
10158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10159         remote_mds_nodsh && skip "remote MDS with nodsh"
10160
10161 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10162         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10163                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10164         [ -z "$old_rr" ] && skip "no QOS"
10165         do_facet $SINGLEMDS lctl set_param \
10166                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10167         mkdir -p $DIR/$tdir
10168         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10169         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10170         do_facet $SINGLEMDS lctl set_param fail_loc=0
10171         rm -rf $DIR/$tdir
10172         do_facet $SINGLEMDS lctl set_param \
10173                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10174 }
10175 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10176
10177 test_117() # bug 10891
10178 {
10179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10180
10181         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10182         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10183         lctl set_param fail_loc=0x21e
10184         > $DIR/$tfile || error "truncate failed"
10185         lctl set_param fail_loc=0
10186         echo "Truncate succeeded."
10187         rm -f $DIR/$tfile
10188 }
10189 run_test 117 "verify osd extend =========="
10190
10191 NO_SLOW_RESENDCOUNT=4
10192 export OLD_RESENDCOUNT=""
10193 set_resend_count () {
10194         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10195         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10196         lctl set_param -n $PROC_RESENDCOUNT $1
10197         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10198 }
10199
10200 # for reduce test_118* time (b=14842)
10201 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10202
10203 # Reset async IO behavior after error case
10204 reset_async() {
10205         FILE=$DIR/reset_async
10206
10207         # Ensure all OSCs are cleared
10208         $LFS setstripe -c -1 $FILE
10209         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10210         sync
10211         rm $FILE
10212 }
10213
10214 test_118a() #bug 11710
10215 {
10216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10217
10218         reset_async
10219
10220         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10221         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10222         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10223
10224         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10225                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10226                 return 1;
10227         fi
10228         rm -f $DIR/$tfile
10229 }
10230 run_test 118a "verify O_SYNC works =========="
10231
10232 test_118b()
10233 {
10234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10235         remote_ost_nodsh && skip "remote OST with nodsh"
10236
10237         reset_async
10238
10239         #define OBD_FAIL_SRV_ENOENT 0x217
10240         set_nodes_failloc "$(osts_nodes)" 0x217
10241         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10242         RC=$?
10243         set_nodes_failloc "$(osts_nodes)" 0
10244         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10245         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10246                     grep -c writeback)
10247
10248         if [[ $RC -eq 0 ]]; then
10249                 error "Must return error due to dropped pages, rc=$RC"
10250                 return 1;
10251         fi
10252
10253         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10254                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10255                 return 1;
10256         fi
10257
10258         echo "Dirty pages not leaked on ENOENT"
10259
10260         # Due to the above error the OSC will issue all RPCs syncronously
10261         # until a subsequent RPC completes successfully without error.
10262         $MULTIOP $DIR/$tfile Ow4096yc
10263         rm -f $DIR/$tfile
10264
10265         return 0
10266 }
10267 run_test 118b "Reclaim dirty pages on fatal error =========="
10268
10269 test_118c()
10270 {
10271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10272
10273         # for 118c, restore the original resend count, LU-1940
10274         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10275                                 set_resend_count $OLD_RESENDCOUNT
10276         remote_ost_nodsh && skip "remote OST with nodsh"
10277
10278         reset_async
10279
10280         #define OBD_FAIL_OST_EROFS               0x216
10281         set_nodes_failloc "$(osts_nodes)" 0x216
10282
10283         # multiop should block due to fsync until pages are written
10284         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10285         MULTIPID=$!
10286         sleep 1
10287
10288         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10289                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10290         fi
10291
10292         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10293                     grep -c writeback)
10294         if [[ $WRITEBACK -eq 0 ]]; then
10295                 error "No page in writeback, writeback=$WRITEBACK"
10296         fi
10297
10298         set_nodes_failloc "$(osts_nodes)" 0
10299         wait $MULTIPID
10300         RC=$?
10301         if [[ $RC -ne 0 ]]; then
10302                 error "Multiop fsync failed, rc=$RC"
10303         fi
10304
10305         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10306         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10307                     grep -c writeback)
10308         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10309                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10310         fi
10311
10312         rm -f $DIR/$tfile
10313         echo "Dirty pages flushed via fsync on EROFS"
10314         return 0
10315 }
10316 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10317
10318 # continue to use small resend count to reduce test_118* time (b=14842)
10319 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10320
10321 test_118d()
10322 {
10323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10324         remote_ost_nodsh && skip "remote OST with nodsh"
10325
10326         reset_async
10327
10328         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10329         set_nodes_failloc "$(osts_nodes)" 0x214
10330         # multiop should block due to fsync until pages are written
10331         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10332         MULTIPID=$!
10333         sleep 1
10334
10335         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10336                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10337         fi
10338
10339         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10340                     grep -c writeback)
10341         if [[ $WRITEBACK -eq 0 ]]; then
10342                 error "No page in writeback, writeback=$WRITEBACK"
10343         fi
10344
10345         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10346         set_nodes_failloc "$(osts_nodes)" 0
10347
10348         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10349         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10350                     grep -c writeback)
10351         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10352                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10353         fi
10354
10355         rm -f $DIR/$tfile
10356         echo "Dirty pages gaurenteed flushed via fsync"
10357         return 0
10358 }
10359 run_test 118d "Fsync validation inject a delay of the bulk =========="
10360
10361 test_118f() {
10362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10363
10364         reset_async
10365
10366         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10367         lctl set_param fail_loc=0x8000040a
10368
10369         # Should simulate EINVAL error which is fatal
10370         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10371         RC=$?
10372         if [[ $RC -eq 0 ]]; then
10373                 error "Must return error due to dropped pages, rc=$RC"
10374         fi
10375
10376         lctl set_param fail_loc=0x0
10377
10378         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10379         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10380         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10381                     grep -c writeback)
10382         if [[ $LOCKED -ne 0 ]]; then
10383                 error "Locked pages remain in cache, locked=$LOCKED"
10384         fi
10385
10386         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10387                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10388         fi
10389
10390         rm -f $DIR/$tfile
10391         echo "No pages locked after fsync"
10392
10393         reset_async
10394         return 0
10395 }
10396 run_test 118f "Simulate unrecoverable OSC side error =========="
10397
10398 test_118g() {
10399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10400
10401         reset_async
10402
10403         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
10404         lctl set_param fail_loc=0x406
10405
10406         # simulate local -ENOMEM
10407         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10408         RC=$?
10409
10410         lctl set_param fail_loc=0
10411         if [[ $RC -eq 0 ]]; then
10412                 error "Must return error due to dropped pages, rc=$RC"
10413         fi
10414
10415         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10416         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10417         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10418                         grep -c writeback)
10419         if [[ $LOCKED -ne 0 ]]; then
10420                 error "Locked pages remain in cache, locked=$LOCKED"
10421         fi
10422
10423         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10424                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10425         fi
10426
10427         rm -f $DIR/$tfile
10428         echo "No pages locked after fsync"
10429
10430         reset_async
10431         return 0
10432 }
10433 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10434
10435 test_118h() {
10436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10437         remote_ost_nodsh && skip "remote OST with nodsh"
10438
10439         reset_async
10440
10441         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10442         set_nodes_failloc "$(osts_nodes)" 0x20e
10443         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10444         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10445         RC=$?
10446
10447         set_nodes_failloc "$(osts_nodes)" 0
10448         if [[ $RC -eq 0 ]]; then
10449                 error "Must return error due to dropped pages, rc=$RC"
10450         fi
10451
10452         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10453         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10454         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10455                     grep -c writeback)
10456         if [[ $LOCKED -ne 0 ]]; then
10457                 error "Locked pages remain in cache, locked=$LOCKED"
10458         fi
10459
10460         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10461                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10462         fi
10463
10464         rm -f $DIR/$tfile
10465         echo "No pages locked after fsync"
10466
10467         return 0
10468 }
10469 run_test 118h "Verify timeout in handling recoverables errors  =========="
10470
10471 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10472
10473 test_118i() {
10474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10475         remote_ost_nodsh && skip "remote OST with nodsh"
10476
10477         reset_async
10478
10479         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10480         set_nodes_failloc "$(osts_nodes)" 0x20e
10481
10482         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10483         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10484         PID=$!
10485         sleep 5
10486         set_nodes_failloc "$(osts_nodes)" 0
10487
10488         wait $PID
10489         RC=$?
10490         if [[ $RC -ne 0 ]]; then
10491                 error "got error, but should be not, rc=$RC"
10492         fi
10493
10494         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10495         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10496         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10497         if [[ $LOCKED -ne 0 ]]; then
10498                 error "Locked pages remain in cache, locked=$LOCKED"
10499         fi
10500
10501         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10502                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10503         fi
10504
10505         rm -f $DIR/$tfile
10506         echo "No pages locked after fsync"
10507
10508         return 0
10509 }
10510 run_test 118i "Fix error before timeout in recoverable error  =========="
10511
10512 [ "$SLOW" = "no" ] && set_resend_count 4
10513
10514 test_118j() {
10515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10516         remote_ost_nodsh && skip "remote OST with nodsh"
10517
10518         reset_async
10519
10520         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10521         set_nodes_failloc "$(osts_nodes)" 0x220
10522
10523         # return -EIO from OST
10524         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10525         RC=$?
10526         set_nodes_failloc "$(osts_nodes)" 0x0
10527         if [[ $RC -eq 0 ]]; then
10528                 error "Must return error due to dropped pages, rc=$RC"
10529         fi
10530
10531         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10532         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10533         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10534         if [[ $LOCKED -ne 0 ]]; then
10535                 error "Locked pages remain in cache, locked=$LOCKED"
10536         fi
10537
10538         # in recoverable error on OST we want resend and stay until it finished
10539         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10540                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10541         fi
10542
10543         rm -f $DIR/$tfile
10544         echo "No pages locked after fsync"
10545
10546         return 0
10547 }
10548 run_test 118j "Simulate unrecoverable OST side error =========="
10549
10550 test_118k()
10551 {
10552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10553         remote_ost_nodsh && skip "remote OSTs with nodsh"
10554
10555         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10556         set_nodes_failloc "$(osts_nodes)" 0x20e
10557         test_mkdir $DIR/$tdir
10558
10559         for ((i=0;i<10;i++)); do
10560                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10561                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10562                 SLEEPPID=$!
10563                 sleep 0.500s
10564                 kill $SLEEPPID
10565                 wait $SLEEPPID
10566         done
10567
10568         set_nodes_failloc "$(osts_nodes)" 0
10569         rm -rf $DIR/$tdir
10570 }
10571 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10572
10573 test_118l() # LU-646
10574 {
10575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10576
10577         test_mkdir $DIR/$tdir
10578         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10579         rm -rf $DIR/$tdir
10580 }
10581 run_test 118l "fsync dir"
10582
10583 test_118m() # LU-3066
10584 {
10585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10586
10587         test_mkdir $DIR/$tdir
10588         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10589         rm -rf $DIR/$tdir
10590 }
10591 run_test 118m "fdatasync dir ========="
10592
10593 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10594
10595 test_118n()
10596 {
10597         local begin
10598         local end
10599
10600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10601         remote_ost_nodsh && skip "remote OSTs with nodsh"
10602
10603         # Sleep to avoid a cached response.
10604         #define OBD_STATFS_CACHE_SECONDS 1
10605         sleep 2
10606
10607         # Inject a 10 second delay in the OST_STATFS handler.
10608         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10609         set_nodes_failloc "$(osts_nodes)" 0x242
10610
10611         begin=$SECONDS
10612         stat --file-system $MOUNT > /dev/null
10613         end=$SECONDS
10614
10615         set_nodes_failloc "$(osts_nodes)" 0
10616
10617         if ((end - begin > 20)); then
10618             error "statfs took $((end - begin)) seconds, expected 10"
10619         fi
10620 }
10621 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10622
10623 test_119a() # bug 11737
10624 {
10625         BSIZE=$((512 * 1024))
10626         directio write $DIR/$tfile 0 1 $BSIZE
10627         # We ask to read two blocks, which is more than a file size.
10628         # directio will indicate an error when requested and actual
10629         # sizes aren't equeal (a normal situation in this case) and
10630         # print actual read amount.
10631         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10632         if [ "$NOB" != "$BSIZE" ]; then
10633                 error "read $NOB bytes instead of $BSIZE"
10634         fi
10635         rm -f $DIR/$tfile
10636 }
10637 run_test 119a "Short directIO read must return actual read amount"
10638
10639 test_119b() # bug 11737
10640 {
10641         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10642
10643         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10644         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10645         sync
10646         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10647                 error "direct read failed"
10648         rm -f $DIR/$tfile
10649 }
10650 run_test 119b "Sparse directIO read must return actual read amount"
10651
10652 test_119c() # bug 13099
10653 {
10654         BSIZE=1048576
10655         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10656         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10657         rm -f $DIR/$tfile
10658 }
10659 run_test 119c "Testing for direct read hitting hole"
10660
10661 test_119d() # bug 15950
10662 {
10663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10664
10665         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10666         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10667         BSIZE=1048576
10668         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10669         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10670         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10671         lctl set_param fail_loc=0x40d
10672         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10673         pid_dio=$!
10674         sleep 1
10675         cat $DIR/$tfile > /dev/null &
10676         lctl set_param fail_loc=0
10677         pid_reads=$!
10678         wait $pid_dio
10679         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10680         sleep 2
10681         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10682         error "the read rpcs have not completed in 2s"
10683         rm -f $DIR/$tfile
10684         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10685 }
10686 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10687
10688 test_120a() {
10689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10690         remote_mds_nodsh && skip "remote MDS with nodsh"
10691         test_mkdir -i0 -c1 $DIR/$tdir
10692         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10693                 skip_env "no early lock cancel on server"
10694
10695         lru_resize_disable mdc
10696         lru_resize_disable osc
10697         cancel_lru_locks mdc
10698         # asynchronous object destroy at MDT could cause bl ast to client
10699         cancel_lru_locks osc
10700
10701         stat $DIR/$tdir > /dev/null
10702         can1=$(do_facet mds1 \
10703                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10704                awk '/ldlm_cancel/ {print $2}')
10705         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10706                awk '/ldlm_bl_callback/ {print $2}')
10707         test_mkdir -i0 -c1 $DIR/$tdir/d1
10708         can2=$(do_facet mds1 \
10709                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10710                awk '/ldlm_cancel/ {print $2}')
10711         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10712                awk '/ldlm_bl_callback/ {print $2}')
10713         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10714         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10715         lru_resize_enable mdc
10716         lru_resize_enable osc
10717 }
10718 run_test 120a "Early Lock Cancel: mkdir test"
10719
10720 test_120b() {
10721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10722         remote_mds_nodsh && skip "remote MDS with nodsh"
10723         test_mkdir $DIR/$tdir
10724         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10725                 skip_env "no early lock cancel on server"
10726
10727         lru_resize_disable mdc
10728         lru_resize_disable osc
10729         cancel_lru_locks mdc
10730         stat $DIR/$tdir > /dev/null
10731         can1=$(do_facet $SINGLEMDS \
10732                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10733                awk '/ldlm_cancel/ {print $2}')
10734         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10735                awk '/ldlm_bl_callback/ {print $2}')
10736         touch $DIR/$tdir/f1
10737         can2=$(do_facet $SINGLEMDS \
10738                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10739                awk '/ldlm_cancel/ {print $2}')
10740         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10741                awk '/ldlm_bl_callback/ {print $2}')
10742         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10743         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10744         lru_resize_enable mdc
10745         lru_resize_enable osc
10746 }
10747 run_test 120b "Early Lock Cancel: create test"
10748
10749 test_120c() {
10750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10751         remote_mds_nodsh && skip "remote MDS with nodsh"
10752         test_mkdir -i0 -c1 $DIR/$tdir
10753         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10754                 skip "no early lock cancel on server"
10755
10756         lru_resize_disable mdc
10757         lru_resize_disable osc
10758         test_mkdir -i0 -c1 $DIR/$tdir/d1
10759         test_mkdir -i0 -c1 $DIR/$tdir/d2
10760         touch $DIR/$tdir/d1/f1
10761         cancel_lru_locks mdc
10762         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10763         can1=$(do_facet mds1 \
10764                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10765                awk '/ldlm_cancel/ {print $2}')
10766         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10767                awk '/ldlm_bl_callback/ {print $2}')
10768         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10769         can2=$(do_facet mds1 \
10770                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10771                awk '/ldlm_cancel/ {print $2}')
10772         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10773                awk '/ldlm_bl_callback/ {print $2}')
10774         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10775         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10776         lru_resize_enable mdc
10777         lru_resize_enable osc
10778 }
10779 run_test 120c "Early Lock Cancel: link test"
10780
10781 test_120d() {
10782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10783         remote_mds_nodsh && skip "remote MDS with nodsh"
10784         test_mkdir -i0 -c1 $DIR/$tdir
10785         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10786                 skip_env "no early lock cancel on server"
10787
10788         lru_resize_disable mdc
10789         lru_resize_disable osc
10790         touch $DIR/$tdir
10791         cancel_lru_locks mdc
10792         stat $DIR/$tdir > /dev/null
10793         can1=$(do_facet mds1 \
10794                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10795                awk '/ldlm_cancel/ {print $2}')
10796         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10797                awk '/ldlm_bl_callback/ {print $2}')
10798         chmod a+x $DIR/$tdir
10799         can2=$(do_facet mds1 \
10800                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10801                awk '/ldlm_cancel/ {print $2}')
10802         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10803                awk '/ldlm_bl_callback/ {print $2}')
10804         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10805         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10806         lru_resize_enable mdc
10807         lru_resize_enable osc
10808 }
10809 run_test 120d "Early Lock Cancel: setattr test"
10810
10811 test_120e() {
10812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10813         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10814                 skip_env "no early lock cancel on server"
10815         remote_mds_nodsh && skip "remote MDS with nodsh"
10816
10817         local dlmtrace_set=false
10818
10819         test_mkdir -i0 -c1 $DIR/$tdir
10820         lru_resize_disable mdc
10821         lru_resize_disable osc
10822         ! $LCTL get_param debug | grep -q dlmtrace &&
10823                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10824         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10825         cancel_lru_locks mdc
10826         cancel_lru_locks osc
10827         dd if=$DIR/$tdir/f1 of=/dev/null
10828         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10829         # XXX client can not do early lock cancel of OST lock
10830         # during unlink (LU-4206), so cancel osc lock now.
10831         sleep 2
10832         cancel_lru_locks osc
10833         can1=$(do_facet mds1 \
10834                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10835                awk '/ldlm_cancel/ {print $2}')
10836         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10837                awk '/ldlm_bl_callback/ {print $2}')
10838         unlink $DIR/$tdir/f1
10839         sleep 5
10840         can2=$(do_facet mds1 \
10841                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10842                awk '/ldlm_cancel/ {print $2}')
10843         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10844                awk '/ldlm_bl_callback/ {print $2}')
10845         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10846                 $LCTL dk $TMP/cancel.debug.txt
10847         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10848                 $LCTL dk $TMP/blocking.debug.txt
10849         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10850         lru_resize_enable mdc
10851         lru_resize_enable osc
10852 }
10853 run_test 120e "Early Lock Cancel: unlink test"
10854
10855 test_120f() {
10856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10857         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10858                 skip_env "no early lock cancel on server"
10859         remote_mds_nodsh && skip "remote MDS with nodsh"
10860
10861         test_mkdir -i0 -c1 $DIR/$tdir
10862         lru_resize_disable mdc
10863         lru_resize_disable osc
10864         test_mkdir -i0 -c1 $DIR/$tdir/d1
10865         test_mkdir -i0 -c1 $DIR/$tdir/d2
10866         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10867         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10868         cancel_lru_locks mdc
10869         cancel_lru_locks osc
10870         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10871         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10872         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10873         # XXX client can not do early lock cancel of OST lock
10874         # during rename (LU-4206), so cancel osc lock now.
10875         sleep 2
10876         cancel_lru_locks osc
10877         can1=$(do_facet mds1 \
10878                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10879                awk '/ldlm_cancel/ {print $2}')
10880         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10881                awk '/ldlm_bl_callback/ {print $2}')
10882         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10883         sleep 5
10884         can2=$(do_facet mds1 \
10885                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10886                awk '/ldlm_cancel/ {print $2}')
10887         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10888                awk '/ldlm_bl_callback/ {print $2}')
10889         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10890         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10891         lru_resize_enable mdc
10892         lru_resize_enable osc
10893 }
10894 run_test 120f "Early Lock Cancel: rename test"
10895
10896 test_120g() {
10897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10898         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10899                 skip_env "no early lock cancel on server"
10900         remote_mds_nodsh && skip "remote MDS with nodsh"
10901
10902         lru_resize_disable mdc
10903         lru_resize_disable osc
10904         count=10000
10905         echo create $count files
10906         test_mkdir $DIR/$tdir
10907         cancel_lru_locks mdc
10908         cancel_lru_locks osc
10909         t0=$(date +%s)
10910
10911         can0=$(do_facet $SINGLEMDS \
10912                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10913                awk '/ldlm_cancel/ {print $2}')
10914         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10915                awk '/ldlm_bl_callback/ {print $2}')
10916         createmany -o $DIR/$tdir/f $count
10917         sync
10918         can1=$(do_facet $SINGLEMDS \
10919                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10920                awk '/ldlm_cancel/ {print $2}')
10921         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10922                awk '/ldlm_bl_callback/ {print $2}')
10923         t1=$(date +%s)
10924         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10925         echo rm $count files
10926         rm -r $DIR/$tdir
10927         sync
10928         can2=$(do_facet $SINGLEMDS \
10929                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10930                awk '/ldlm_cancel/ {print $2}')
10931         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10932                awk '/ldlm_bl_callback/ {print $2}')
10933         t2=$(date +%s)
10934         echo total: $count removes in $((t2-t1))
10935         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10936         sleep 2
10937         # wait for commitment of removal
10938         lru_resize_enable mdc
10939         lru_resize_enable osc
10940 }
10941 run_test 120g "Early Lock Cancel: performance test"
10942
10943 test_121() { #bug #10589
10944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10945
10946         rm -rf $DIR/$tfile
10947         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10948 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10949         lctl set_param fail_loc=0x310
10950         cancel_lru_locks osc > /dev/null
10951         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10952         lctl set_param fail_loc=0
10953         [[ $reads -eq $writes ]] ||
10954                 error "read $reads blocks, must be $writes blocks"
10955 }
10956 run_test 121 "read cancel race ========="
10957
10958 test_123a() { # was test 123, statahead(bug 11401)
10959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10960
10961         SLOWOK=0
10962         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10963                 log "testing UP system. Performance may be lower than expected."
10964                 SLOWOK=1
10965         fi
10966
10967         rm -rf $DIR/$tdir
10968         test_mkdir $DIR/$tdir
10969         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10970         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10971         MULT=10
10972         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10973                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10974
10975                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10976                 lctl set_param -n llite.*.statahead_max 0
10977                 lctl get_param llite.*.statahead_max
10978                 cancel_lru_locks mdc
10979                 cancel_lru_locks osc
10980                 stime=`date +%s`
10981                 time ls -l $DIR/$tdir | wc -l
10982                 etime=`date +%s`
10983                 delta=$((etime - stime))
10984                 log "ls $i files without statahead: $delta sec"
10985                 lctl set_param llite.*.statahead_max=$max
10986
10987                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10988                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10989                 cancel_lru_locks mdc
10990                 cancel_lru_locks osc
10991                 stime=`date +%s`
10992                 time ls -l $DIR/$tdir | wc -l
10993                 etime=`date +%s`
10994                 delta_sa=$((etime - stime))
10995                 log "ls $i files with statahead: $delta_sa sec"
10996                 lctl get_param -n llite.*.statahead_stats
10997                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10998
10999                 [[ $swrong -lt $ewrong ]] &&
11000                         log "statahead was stopped, maybe too many locks held!"
11001                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11002
11003                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11004                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11005                     lctl set_param -n llite.*.statahead_max 0
11006                     lctl get_param llite.*.statahead_max
11007                     cancel_lru_locks mdc
11008                     cancel_lru_locks osc
11009                     stime=`date +%s`
11010                     time ls -l $DIR/$tdir | wc -l
11011                     etime=`date +%s`
11012                     delta=$((etime - stime))
11013                     log "ls $i files again without statahead: $delta sec"
11014                     lctl set_param llite.*.statahead_max=$max
11015                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11016                         if [  $SLOWOK -eq 0 ]; then
11017                                 error "ls $i files is slower with statahead!"
11018                         else
11019                                 log "ls $i files is slower with statahead!"
11020                         fi
11021                         break
11022                     fi
11023                 fi
11024
11025                 [ $delta -gt 20 ] && break
11026                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11027                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11028         done
11029         log "ls done"
11030
11031         stime=`date +%s`
11032         rm -r $DIR/$tdir
11033         sync
11034         etime=`date +%s`
11035         delta=$((etime - stime))
11036         log "rm -r $DIR/$tdir/: $delta seconds"
11037         log "rm done"
11038         lctl get_param -n llite.*.statahead_stats
11039 }
11040 run_test 123a "verify statahead work"
11041
11042 test_123b () { # statahead(bug 15027)
11043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11044
11045         test_mkdir $DIR/$tdir
11046         createmany -o $DIR/$tdir/$tfile-%d 1000
11047
11048         cancel_lru_locks mdc
11049         cancel_lru_locks osc
11050
11051 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11052         lctl set_param fail_loc=0x80000803
11053         ls -lR $DIR/$tdir > /dev/null
11054         log "ls done"
11055         lctl set_param fail_loc=0x0
11056         lctl get_param -n llite.*.statahead_stats
11057         rm -r $DIR/$tdir
11058         sync
11059
11060 }
11061 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11062
11063 test_124a() {
11064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11065         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11066                 skip_env "no lru resize on server"
11067
11068         local NR=2000
11069
11070         test_mkdir $DIR/$tdir
11071
11072         log "create $NR files at $DIR/$tdir"
11073         createmany -o $DIR/$tdir/f $NR ||
11074                 error "failed to create $NR files in $DIR/$tdir"
11075
11076         cancel_lru_locks mdc
11077         ls -l $DIR/$tdir > /dev/null
11078
11079         local NSDIR=""
11080         local LRU_SIZE=0
11081         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11082                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11083                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11084                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11085                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11086                         log "NSDIR=$NSDIR"
11087                         log "NS=$(basename $NSDIR)"
11088                         break
11089                 fi
11090         done
11091
11092         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11093                 skip "Not enough cached locks created!"
11094         fi
11095         log "LRU=$LRU_SIZE"
11096
11097         local SLEEP=30
11098
11099         # We know that lru resize allows one client to hold $LIMIT locks
11100         # for 10h. After that locks begin to be killed by client.
11101         local MAX_HRS=10
11102         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11103         log "LIMIT=$LIMIT"
11104         if [ $LIMIT -lt $LRU_SIZE ]; then
11105                 skip "Limit is too small $LIMIT"
11106         fi
11107
11108         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11109         # killing locks. Some time was spent for creating locks. This means
11110         # that up to the moment of sleep finish we must have killed some of
11111         # them (10-100 locks). This depends on how fast ther were created.
11112         # Many of them were touched in almost the same moment and thus will
11113         # be killed in groups.
11114         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11115
11116         # Use $LRU_SIZE_B here to take into account real number of locks
11117         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11118         local LRU_SIZE_B=$LRU_SIZE
11119         log "LVF=$LVF"
11120         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11121         log "OLD_LVF=$OLD_LVF"
11122         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11123
11124         # Let's make sure that we really have some margin. Client checks
11125         # cached locks every 10 sec.
11126         SLEEP=$((SLEEP+20))
11127         log "Sleep ${SLEEP} sec"
11128         local SEC=0
11129         while ((SEC<$SLEEP)); do
11130                 echo -n "..."
11131                 sleep 5
11132                 SEC=$((SEC+5))
11133                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11134                 echo -n "$LRU_SIZE"
11135         done
11136         echo ""
11137         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11138         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11139
11140         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11141                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11142                 unlinkmany $DIR/$tdir/f $NR
11143                 return
11144         }
11145
11146         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11147         log "unlink $NR files at $DIR/$tdir"
11148         unlinkmany $DIR/$tdir/f $NR
11149 }
11150 run_test 124a "lru resize ======================================="
11151
11152 get_max_pool_limit()
11153 {
11154         local limit=$($LCTL get_param \
11155                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11156         local max=0
11157         for l in $limit; do
11158                 if [[ $l -gt $max ]]; then
11159                         max=$l
11160                 fi
11161         done
11162         echo $max
11163 }
11164
11165 test_124b() {
11166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11167         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11168                 skip_env "no lru resize on server"
11169
11170         LIMIT=$(get_max_pool_limit)
11171
11172         NR=$(($(default_lru_size)*20))
11173         if [[ $NR -gt $LIMIT ]]; then
11174                 log "Limit lock number by $LIMIT locks"
11175                 NR=$LIMIT
11176         fi
11177
11178         IFree=$(mdsrate_inodes_available)
11179         if [ $IFree -lt $NR ]; then
11180                 log "Limit lock number by $IFree inodes"
11181                 NR=$IFree
11182         fi
11183
11184         lru_resize_disable mdc
11185         test_mkdir -p $DIR/$tdir/disable_lru_resize
11186
11187         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11188         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11189         cancel_lru_locks mdc
11190         stime=`date +%s`
11191         PID=""
11192         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11193         PID="$PID $!"
11194         sleep 2
11195         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11196         PID="$PID $!"
11197         sleep 2
11198         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11199         PID="$PID $!"
11200         wait $PID
11201         etime=`date +%s`
11202         nolruresize_delta=$((etime-stime))
11203         log "ls -la time: $nolruresize_delta seconds"
11204         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11205         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11206
11207         lru_resize_enable mdc
11208         test_mkdir -p $DIR/$tdir/enable_lru_resize
11209
11210         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11211         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11212         cancel_lru_locks mdc
11213         stime=`date +%s`
11214         PID=""
11215         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11216         PID="$PID $!"
11217         sleep 2
11218         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11219         PID="$PID $!"
11220         sleep 2
11221         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11222         PID="$PID $!"
11223         wait $PID
11224         etime=`date +%s`
11225         lruresize_delta=$((etime-stime))
11226         log "ls -la time: $lruresize_delta seconds"
11227         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11228
11229         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11230                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11231         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11232                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11233         else
11234                 log "lru resize performs the same with no lru resize"
11235         fi
11236         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11237 }
11238 run_test 124b "lru resize (performance test) ======================="
11239
11240 test_124c() {
11241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11242         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11243                 skip_env "no lru resize on server"
11244
11245         # cache ununsed locks on client
11246         local nr=100
11247         cancel_lru_locks mdc
11248         test_mkdir $DIR/$tdir
11249         createmany -o $DIR/$tdir/f $nr ||
11250                 error "failed to create $nr files in $DIR/$tdir"
11251         ls -l $DIR/$tdir > /dev/null
11252
11253         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11254         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11255         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11256         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11257         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11258
11259         # set lru_max_age to 1 sec
11260         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11261         echo "sleep $((recalc_p * 2)) seconds..."
11262         sleep $((recalc_p * 2))
11263
11264         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11265         # restore lru_max_age
11266         $LCTL set_param -n $nsdir.lru_max_age $max_age
11267         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11268         unlinkmany $DIR/$tdir/f $nr
11269 }
11270 run_test 124c "LRUR cancel very aged locks"
11271
11272 test_124d() {
11273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11274         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11275                 skip_env "no lru resize on server"
11276
11277         # cache ununsed locks on client
11278         local nr=100
11279
11280         lru_resize_disable mdc
11281         stack_trap "lru_resize_enable mdc" EXIT
11282
11283         cancel_lru_locks mdc
11284
11285         # asynchronous object destroy at MDT could cause bl ast to client
11286         test_mkdir $DIR/$tdir
11287         createmany -o $DIR/$tdir/f $nr ||
11288                 error "failed to create $nr files in $DIR/$tdir"
11289         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11290
11291         ls -l $DIR/$tdir > /dev/null
11292
11293         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11294         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11295         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11296         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11297
11298         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11299
11300         # set lru_max_age to 1 sec
11301         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11302         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11303
11304         echo "sleep $((recalc_p * 2)) seconds..."
11305         sleep $((recalc_p * 2))
11306
11307         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11308
11309         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11310 }
11311 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11312
11313 test_125() { # 13358
11314         $LCTL get_param -n llite.*.client_type | grep -q local ||
11315                 skip "must run as local client"
11316         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11317                 skip_env "must have acl enabled"
11318         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11319
11320         test_mkdir $DIR/$tdir
11321         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11322         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
11323         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
11324 }
11325 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
11326
11327 test_126() { # bug 12829/13455
11328         $GSS && skip_env "must run as gss disabled"
11329         $LCTL get_param -n llite.*.client_type | grep -q local ||
11330                 skip "must run as local client"
11331         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
11332
11333         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
11334         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
11335         rm -f $DIR/$tfile
11336         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
11337 }
11338 run_test 126 "check that the fsgid provided by the client is taken into account"
11339
11340 test_127a() { # bug 15521
11341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11342
11343         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
11344         $LCTL set_param osc.*.stats=0
11345         FSIZE=$((2048 * 1024))
11346         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
11347         cancel_lru_locks osc
11348         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
11349
11350         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
11351         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
11352                 echo "got $COUNT $NAME"
11353                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
11354                 eval $NAME=$COUNT || error "Wrong proc format"
11355
11356                 case $NAME in
11357                         read_bytes|write_bytes)
11358                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
11359                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
11360                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
11361                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
11362                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
11363                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
11364                                 error "sumsquare is too small: $SUMSQ"
11365                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
11366                                 error "sumsquare is too big: $SUMSQ"
11367                         ;;
11368                         *) ;;
11369                 esac
11370         done < $DIR/${tfile}.tmp
11371
11372         #check that we actually got some stats
11373         [ "$read_bytes" ] || error "Missing read_bytes stats"
11374         [ "$write_bytes" ] || error "Missing write_bytes stats"
11375         [ "$read_bytes" != 0 ] || error "no read done"
11376         [ "$write_bytes" != 0 ] || error "no write done"
11377 }
11378 run_test 127a "verify the client stats are sane"
11379
11380 test_127b() { # bug LU-333
11381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11382         local name count samp unit min max sum sumsq
11383
11384         $LCTL set_param llite.*.stats=0
11385
11386         # perform 2 reads and writes so MAX is different from SUM.
11387         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11388         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11389         cancel_lru_locks osc
11390         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11391         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11392
11393         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
11394         while read name count samp unit min max sum sumsq; do
11395                 echo "got $count $name"
11396                 eval $name=$count || error "Wrong proc format"
11397
11398                 case $name in
11399                 read_bytes)
11400                         [ $count -ne 2 ] && error "count is not 2: $count"
11401                         [ $min -ne $PAGE_SIZE ] &&
11402                                 error "min is not $PAGE_SIZE: $min"
11403                         [ $max -ne $PAGE_SIZE ] &&
11404                                 error "max is incorrect: $max"
11405                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
11406                                 error "sum is wrong: $sum"
11407                         ;;
11408                 write_bytes)
11409                         [ $count -ne 2 ] && error "count is not 2: $count"
11410                         [ $min -ne $PAGE_SIZE ] &&
11411                                 error "min is not $PAGE_SIZE: $min"
11412                         [ $max -ne $PAGE_SIZE ] &&
11413                                 error "max is incorrect: $max"
11414                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
11415                                 error "sum is wrong: $sum"
11416                         ;;
11417                 *) ;;
11418                 esac
11419         done < $TMP/$tfile.tmp
11420
11421         #check that we actually got some stats
11422         [ "$read_bytes" ] || error "Missing read_bytes stats"
11423         [ "$write_bytes" ] || error "Missing write_bytes stats"
11424         [ "$read_bytes" != 0 ] || error "no read done"
11425         [ "$write_bytes" != 0 ] || error "no write done"
11426
11427         rm -f $TMP/${tfile}.tmp
11428 }
11429 run_test 127b "verify the llite client stats are sane"
11430
11431 test_127c() { # LU-12394
11432         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11433         local size
11434         local bsize
11435         local reads
11436         local writes
11437         local count
11438
11439         $LCTL set_param llite.*.extents_stats=1
11440         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
11441
11442         # Use two stripes so there is enough space in default config
11443         $LFS setstripe -c 2 $DIR/$tfile
11444
11445         # Extent stats start at 0-4K and go in power of two buckets
11446         # LL_HIST_START = 12 --> 2^12 = 4K
11447         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
11448         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
11449         # small configs
11450         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
11451                 do
11452                 # Write and read, 2x each, second time at a non-zero offset
11453                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
11454                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
11455                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
11456                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
11457                 rm -f $DIR/$tfile
11458         done
11459
11460         $LCTL get_param llite.*.extents_stats
11461
11462         count=2
11463         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
11464                 do
11465                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
11466                                 grep -m 1 $bsize)
11467                 reads=$(echo $bucket | awk '{print $5}')
11468                 writes=$(echo $bucket | awk '{print $9}')
11469                 [ "$reads" -eq $count ] ||
11470                         error "$reads reads in < $bsize bucket, expect $count"
11471                 [ "$writes" -eq $count ] ||
11472                         error "$writes writes in < $bsize bucket, expect $count"
11473         done
11474
11475         # Test mmap write and read
11476         $LCTL set_param llite.*.extents_stats=c
11477         size=512
11478         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
11479         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
11480         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
11481
11482         $LCTL get_param llite.*.extents_stats
11483
11484         count=$(((size*1024) / PAGE_SIZE))
11485
11486         bsize=$((2 * PAGE_SIZE / 1024))K
11487
11488         bucket=$($LCTL get_param -n llite.*.extents_stats |
11489                         grep -m 1 $bsize)
11490         reads=$(echo $bucket | awk '{print $5}')
11491         writes=$(echo $bucket | awk '{print $9}')
11492         # mmap writes fault in the page first, creating an additonal read
11493         [ "$reads" -eq $((2 * count)) ] ||
11494                 error "$reads reads in < $bsize bucket, expect $count"
11495         [ "$writes" -eq $count ] ||
11496                 error "$writes writes in < $bsize bucket, expect $count"
11497 }
11498 run_test 127c "test llite extent stats with regular & mmap i/o"
11499
11500 test_128() { # bug 15212
11501         touch $DIR/$tfile
11502         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11503                 find $DIR/$tfile
11504                 find $DIR/$tfile
11505         EOF
11506
11507         result=$(grep error $TMP/$tfile.log)
11508         rm -f $DIR/$tfile $TMP/$tfile.log
11509         [ -z "$result" ] ||
11510                 error "consecutive find's under interactive lfs failed"
11511 }
11512 run_test 128 "interactive lfs for 2 consecutive find's"
11513
11514 set_dir_limits () {
11515         local mntdev
11516         local canondev
11517         local node
11518
11519         local ldproc=/proc/fs/ldiskfs
11520         local facets=$(get_facets MDS)
11521
11522         for facet in ${facets//,/ }; do
11523                 canondev=$(ldiskfs_canon \
11524                            *.$(convert_facet2label $facet).mntdev $facet)
11525                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11526                         ldproc=/sys/fs/ldiskfs
11527                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11528                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11529         done
11530 }
11531
11532 check_mds_dmesg() {
11533         local facets=$(get_facets MDS)
11534         for facet in ${facets//,/ }; do
11535                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11536         done
11537         return 1
11538 }
11539
11540 test_129() {
11541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11542         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11543                 skip "Need MDS version with at least 2.5.56"
11544         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11545                 skip_env "ldiskfs only test"
11546         fi
11547         remote_mds_nodsh && skip "remote MDS with nodsh"
11548
11549         local ENOSPC=28
11550         local EFBIG=27
11551         local has_warning=false
11552
11553         rm -rf $DIR/$tdir
11554         mkdir -p $DIR/$tdir
11555
11556         # block size of mds1
11557         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11558         set_dir_limits $maxsize $maxsize
11559         local dirsize=$(stat -c%s "$DIR/$tdir")
11560         local nfiles=0
11561         while [[ $dirsize -le $maxsize ]]; do
11562                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11563                 rc=$?
11564                 if ! $has_warning; then
11565                         check_mds_dmesg '"is approaching"' && has_warning=true
11566                 fi
11567                 # check two errors:
11568                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11569                 # EFBIG for previous versions included in ldiskfs series
11570                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11571                         set_dir_limits 0 0
11572                         echo "return code $rc received as expected"
11573
11574                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11575                                 error_exit "create failed w/o dir size limit"
11576
11577                         check_mds_dmesg '"has reached"' ||
11578                                 error_exit "reached message should be output"
11579
11580                         [ $has_warning = "false" ] &&
11581                                 error_exit "warning message should be output"
11582
11583                         dirsize=$(stat -c%s "$DIR/$tdir")
11584
11585                         [[ $dirsize -ge $maxsize ]] && return 0
11586                         error_exit "current dir size $dirsize, " \
11587                                    "previous limit $maxsize"
11588                 elif [ $rc -ne 0 ]; then
11589                         set_dir_limits 0 0
11590                         error_exit "return $rc received instead of expected " \
11591                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11592                 fi
11593                 nfiles=$((nfiles + 1))
11594                 dirsize=$(stat -c%s "$DIR/$tdir")
11595         done
11596
11597         set_dir_limits 0 0
11598         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11599 }
11600 run_test 129 "test directory size limit ========================"
11601
11602 OLDIFS="$IFS"
11603 cleanup_130() {
11604         trap 0
11605         IFS="$OLDIFS"
11606 }
11607
11608 test_130a() {
11609         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11610         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11611
11612         trap cleanup_130 EXIT RETURN
11613
11614         local fm_file=$DIR/$tfile
11615         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11616         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11617                 error "dd failed for $fm_file"
11618
11619         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11620         filefrag -ves $fm_file
11621         RC=$?
11622         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11623                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11624         [ $RC != 0 ] && error "filefrag $fm_file failed"
11625
11626         filefrag_op=$(filefrag -ve -k $fm_file |
11627                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11628         lun=$($LFS getstripe -i $fm_file)
11629
11630         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11631         IFS=$'\n'
11632         tot_len=0
11633         for line in $filefrag_op
11634         do
11635                 frag_lun=`echo $line | cut -d: -f5`
11636                 ext_len=`echo $line | cut -d: -f4`
11637                 if (( $frag_lun != $lun )); then
11638                         cleanup_130
11639                         error "FIEMAP on 1-stripe file($fm_file) failed"
11640                         return
11641                 fi
11642                 (( tot_len += ext_len ))
11643         done
11644
11645         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11646                 cleanup_130
11647                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11648                 return
11649         fi
11650
11651         cleanup_130
11652
11653         echo "FIEMAP on single striped file succeeded"
11654 }
11655 run_test 130a "FIEMAP (1-stripe file)"
11656
11657 test_130b() {
11658         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11659
11660         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11661         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11662
11663         trap cleanup_130 EXIT RETURN
11664
11665         local fm_file=$DIR/$tfile
11666         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11667                         error "setstripe on $fm_file"
11668         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11669                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11670
11671         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11672                 error "dd failed on $fm_file"
11673
11674         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11675         filefrag_op=$(filefrag -ve -k $fm_file |
11676                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11677
11678         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11679                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11680
11681         IFS=$'\n'
11682         tot_len=0
11683         num_luns=1
11684         for line in $filefrag_op
11685         do
11686                 frag_lun=$(echo $line | cut -d: -f5 |
11687                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11688                 ext_len=$(echo $line | cut -d: -f4)
11689                 if (( $frag_lun != $last_lun )); then
11690                         if (( tot_len != 1024 )); then
11691                                 cleanup_130
11692                                 error "FIEMAP on $fm_file failed; returned " \
11693                                 "len $tot_len for OST $last_lun instead of 1024"
11694                                 return
11695                         else
11696                                 (( num_luns += 1 ))
11697                                 tot_len=0
11698                         fi
11699                 fi
11700                 (( tot_len += ext_len ))
11701                 last_lun=$frag_lun
11702         done
11703         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11704                 cleanup_130
11705                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11706                         "luns or wrong len for OST $last_lun"
11707                 return
11708         fi
11709
11710         cleanup_130
11711
11712         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11713 }
11714 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11715
11716 test_130c() {
11717         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11718
11719         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11720         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11721
11722         trap cleanup_130 EXIT RETURN
11723
11724         local fm_file=$DIR/$tfile
11725         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11726         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11727                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11728
11729         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11730                         error "dd failed on $fm_file"
11731
11732         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11733         filefrag_op=$(filefrag -ve -k $fm_file |
11734                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11735
11736         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11737                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11738
11739         IFS=$'\n'
11740         tot_len=0
11741         num_luns=1
11742         for line in $filefrag_op
11743         do
11744                 frag_lun=$(echo $line | cut -d: -f5 |
11745                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11746                 ext_len=$(echo $line | cut -d: -f4)
11747                 if (( $frag_lun != $last_lun )); then
11748                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11749                         if (( logical != 512 )); then
11750                                 cleanup_130
11751                                 error "FIEMAP on $fm_file failed; returned " \
11752                                 "logical start for lun $logical instead of 512"
11753                                 return
11754                         fi
11755                         if (( tot_len != 512 )); then
11756                                 cleanup_130
11757                                 error "FIEMAP on $fm_file failed; returned " \
11758                                 "len $tot_len for OST $last_lun instead of 1024"
11759                                 return
11760                         else
11761                                 (( num_luns += 1 ))
11762                                 tot_len=0
11763                         fi
11764                 fi
11765                 (( tot_len += ext_len ))
11766                 last_lun=$frag_lun
11767         done
11768         if (( num_luns != 2 || tot_len != 512 )); then
11769                 cleanup_130
11770                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11771                         "luns or wrong len for OST $last_lun"
11772                 return
11773         fi
11774
11775         cleanup_130
11776
11777         echo "FIEMAP on 2-stripe file with hole succeeded"
11778 }
11779 run_test 130c "FIEMAP (2-stripe file with hole)"
11780
11781 test_130d() {
11782         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11783
11784         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11785         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11786
11787         trap cleanup_130 EXIT RETURN
11788
11789         local fm_file=$DIR/$tfile
11790         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11791                         error "setstripe on $fm_file"
11792         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11793                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11794
11795         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11796         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11797                 error "dd failed on $fm_file"
11798
11799         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11800         filefrag_op=$(filefrag -ve -k $fm_file |
11801                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11802
11803         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11804                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11805
11806         IFS=$'\n'
11807         tot_len=0
11808         num_luns=1
11809         for line in $filefrag_op
11810         do
11811                 frag_lun=$(echo $line | cut -d: -f5 |
11812                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11813                 ext_len=$(echo $line | cut -d: -f4)
11814                 if (( $frag_lun != $last_lun )); then
11815                         if (( tot_len != 1024 )); then
11816                                 cleanup_130
11817                                 error "FIEMAP on $fm_file failed; returned " \
11818                                 "len $tot_len for OST $last_lun instead of 1024"
11819                                 return
11820                         else
11821                                 (( num_luns += 1 ))
11822                                 tot_len=0
11823                         fi
11824                 fi
11825                 (( tot_len += ext_len ))
11826                 last_lun=$frag_lun
11827         done
11828         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11829                 cleanup_130
11830                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11831                         "luns or wrong len for OST $last_lun"
11832                 return
11833         fi
11834
11835         cleanup_130
11836
11837         echo "FIEMAP on N-stripe file succeeded"
11838 }
11839 run_test 130d "FIEMAP (N-stripe file)"
11840
11841 test_130e() {
11842         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11843
11844         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11845         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11846
11847         trap cleanup_130 EXIT RETURN
11848
11849         local fm_file=$DIR/$tfile
11850         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11851         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11852                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11853
11854         NUM_BLKS=512
11855         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11856         for ((i = 0; i < $NUM_BLKS; i++))
11857         do
11858                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11859         done
11860
11861         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11862         filefrag_op=$(filefrag -ve -k $fm_file |
11863                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11864
11865         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11866                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11867
11868         IFS=$'\n'
11869         tot_len=0
11870         num_luns=1
11871         for line in $filefrag_op
11872         do
11873                 frag_lun=$(echo $line | cut -d: -f5 |
11874                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11875                 ext_len=$(echo $line | cut -d: -f4)
11876                 if (( $frag_lun != $last_lun )); then
11877                         if (( tot_len != $EXPECTED_LEN )); then
11878                                 cleanup_130
11879                                 error "FIEMAP on $fm_file failed; returned " \
11880                                 "len $tot_len for OST $last_lun instead " \
11881                                 "of $EXPECTED_LEN"
11882                                 return
11883                         else
11884                                 (( num_luns += 1 ))
11885                                 tot_len=0
11886                         fi
11887                 fi
11888                 (( tot_len += ext_len ))
11889                 last_lun=$frag_lun
11890         done
11891         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11892                 cleanup_130
11893                 error "FIEMAP on $fm_file failed; returned wrong number " \
11894                         "of luns or wrong len for OST $last_lun"
11895                 return
11896         fi
11897
11898         cleanup_130
11899
11900         echo "FIEMAP with continuation calls succeeded"
11901 }
11902 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11903
11904 test_130f() {
11905         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11906         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11907
11908         local fm_file=$DIR/$tfile
11909         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
11910                 error "multiop create with lov_delay_create on $fm_file"
11911
11912         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11913         filefrag_extents=$(filefrag -vek $fm_file |
11914                            awk '/extents? found/ { print $2 }')
11915         if [[ "$filefrag_extents" != "0" ]]; then
11916                 error "FIEMAP on $fm_file failed; " \
11917                       "returned $filefrag_extents expected 0"
11918         fi
11919
11920         rm -f $fm_file
11921 }
11922 run_test 130f "FIEMAP (unstriped file)"
11923
11924 # Test for writev/readv
11925 test_131a() {
11926         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
11927                 error "writev test failed"
11928         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
11929                 error "readv failed"
11930         rm -f $DIR/$tfile
11931 }
11932 run_test 131a "test iov's crossing stripe boundary for writev/readv"
11933
11934 test_131b() {
11935         local fsize=$((524288 + 1048576 + 1572864))
11936         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
11937                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11938                         error "append writev test failed"
11939
11940         ((fsize += 1572864 + 1048576))
11941         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
11942                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11943                         error "append writev test failed"
11944         rm -f $DIR/$tfile
11945 }
11946 run_test 131b "test append writev"
11947
11948 test_131c() {
11949         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
11950         error "NOT PASS"
11951 }
11952 run_test 131c "test read/write on file w/o objects"
11953
11954 test_131d() {
11955         rwv -f $DIR/$tfile -w -n 1 1572864
11956         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
11957         if [ "$NOB" != 1572864 ]; then
11958                 error "Short read filed: read $NOB bytes instead of 1572864"
11959         fi
11960         rm -f $DIR/$tfile
11961 }
11962 run_test 131d "test short read"
11963
11964 test_131e() {
11965         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
11966         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
11967         error "read hitting hole failed"
11968         rm -f $DIR/$tfile
11969 }
11970 run_test 131e "test read hitting hole"
11971
11972 check_stats() {
11973         local facet=$1
11974         local op=$2
11975         local want=${3:-0}
11976         local res
11977
11978         case $facet in
11979         mds*) res=$(do_facet $facet \
11980                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
11981                  ;;
11982         ost*) res=$(do_facet $facet \
11983                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
11984                  ;;
11985         *) error "Wrong facet '$facet'" ;;
11986         esac
11987         [ "$res" ] || error "The counter for $op on $facet was not incremented"
11988         # if the argument $3 is zero, it means any stat increment is ok.
11989         if [[ $want -gt 0 ]]; then
11990                 local count=$(echo $res | awk '{ print $2 }')
11991                 [[ $count -ne $want ]] &&
11992                         error "The $op counter on $facet is $count, not $want"
11993         fi
11994 }
11995
11996 test_133a() {
11997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11998         remote_ost_nodsh && skip "remote OST with nodsh"
11999         remote_mds_nodsh && skip "remote MDS with nodsh"
12000         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12001                 skip_env "MDS doesn't support rename stats"
12002
12003         local testdir=$DIR/${tdir}/stats_testdir
12004
12005         mkdir -p $DIR/${tdir}
12006
12007         # clear stats.
12008         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12009         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12010
12011         # verify mdt stats first.
12012         mkdir ${testdir} || error "mkdir failed"
12013         check_stats $SINGLEMDS "mkdir" 1
12014         touch ${testdir}/${tfile} || error "touch failed"
12015         check_stats $SINGLEMDS "open" 1
12016         check_stats $SINGLEMDS "close" 1
12017         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12018                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12019                 check_stats $SINGLEMDS "mknod" 2
12020         }
12021         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12022         check_stats $SINGLEMDS "unlink" 1
12023         rm -f ${testdir}/${tfile} || error "file remove failed"
12024         check_stats $SINGLEMDS "unlink" 2
12025
12026         # remove working dir and check mdt stats again.
12027         rmdir ${testdir} || error "rmdir failed"
12028         check_stats $SINGLEMDS "rmdir" 1
12029
12030         local testdir1=$DIR/${tdir}/stats_testdir1
12031         mkdir -p ${testdir}
12032         mkdir -p ${testdir1}
12033         touch ${testdir1}/test1
12034         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12035         check_stats $SINGLEMDS "crossdir_rename" 1
12036
12037         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12038         check_stats $SINGLEMDS "samedir_rename" 1
12039
12040         rm -rf $DIR/${tdir}
12041 }
12042 run_test 133a "Verifying MDT stats ========================================"
12043
12044 test_133b() {
12045         local res
12046
12047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12048         remote_ost_nodsh && skip "remote OST with nodsh"
12049         remote_mds_nodsh && skip "remote MDS with nodsh"
12050
12051         local testdir=$DIR/${tdir}/stats_testdir
12052
12053         mkdir -p ${testdir} || error "mkdir failed"
12054         touch ${testdir}/${tfile} || error "touch failed"
12055         cancel_lru_locks mdc
12056
12057         # clear stats.
12058         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12059         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12060
12061         # extra mdt stats verification.
12062         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12063         check_stats $SINGLEMDS "setattr" 1
12064         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12065         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12066         then            # LU-1740
12067                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12068                 check_stats $SINGLEMDS "getattr" 1
12069         fi
12070         rm -rf $DIR/${tdir}
12071
12072         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12073         # so the check below is not reliable
12074         [ $MDSCOUNT -eq 1 ] || return 0
12075
12076         # Sleep to avoid a cached response.
12077         #define OBD_STATFS_CACHE_SECONDS 1
12078         sleep 2
12079         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12080         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12081         $LFS df || error "lfs failed"
12082         check_stats $SINGLEMDS "statfs" 1
12083
12084         # check aggregated statfs (LU-10018)
12085         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12086                 return 0
12087         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12088                 return 0
12089         sleep 2
12090         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12091         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12092         df $DIR
12093         check_stats $SINGLEMDS "statfs" 1
12094
12095         # We want to check that the client didn't send OST_STATFS to
12096         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12097         # extra care is needed here.
12098         if remote_mds; then
12099                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12100                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12101
12102                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12103                 [ "$res" ] && error "OST got STATFS"
12104         fi
12105
12106         return 0
12107 }
12108 run_test 133b "Verifying extra MDT stats =================================="
12109
12110 test_133c() {
12111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12112         remote_ost_nodsh && skip "remote OST with nodsh"
12113         remote_mds_nodsh && skip "remote MDS with nodsh"
12114
12115         local testdir=$DIR/$tdir/stats_testdir
12116
12117         test_mkdir -p $testdir
12118
12119         # verify obdfilter stats.
12120         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12121         sync
12122         cancel_lru_locks osc
12123         wait_delete_completed
12124
12125         # clear stats.
12126         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12127         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12128
12129         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12130                 error "dd failed"
12131         sync
12132         cancel_lru_locks osc
12133         check_stats ost1 "write" 1
12134
12135         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12136         check_stats ost1 "read" 1
12137
12138         > $testdir/$tfile || error "truncate failed"
12139         check_stats ost1 "punch" 1
12140
12141         rm -f $testdir/$tfile || error "file remove failed"
12142         wait_delete_completed
12143         check_stats ost1 "destroy" 1
12144
12145         rm -rf $DIR/$tdir
12146 }
12147 run_test 133c "Verifying OST stats ========================================"
12148
12149 order_2() {
12150         local value=$1
12151         local orig=$value
12152         local order=1
12153
12154         while [ $value -ge 2 ]; do
12155                 order=$((order*2))
12156                 value=$((value/2))
12157         done
12158
12159         if [ $orig -gt $order ]; then
12160                 order=$((order*2))
12161         fi
12162         echo $order
12163 }
12164
12165 size_in_KMGT() {
12166     local value=$1
12167     local size=('K' 'M' 'G' 'T');
12168     local i=0
12169     local size_string=$value
12170
12171     while [ $value -ge 1024 ]; do
12172         if [ $i -gt 3 ]; then
12173             #T is the biggest unit we get here, if that is bigger,
12174             #just return XXXT
12175             size_string=${value}T
12176             break
12177         fi
12178         value=$((value >> 10))
12179         if [ $value -lt 1024 ]; then
12180             size_string=${value}${size[$i]}
12181             break
12182         fi
12183         i=$((i + 1))
12184     done
12185
12186     echo $size_string
12187 }
12188
12189 get_rename_size() {
12190         local size=$1
12191         local context=${2:-.}
12192         local sample=$(do_facet $SINGLEMDS $LCTL \
12193                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12194                 grep -A1 $context |
12195                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12196         echo $sample
12197 }
12198
12199 test_133d() {
12200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12201         remote_ost_nodsh && skip "remote OST with nodsh"
12202         remote_mds_nodsh && skip "remote MDS with nodsh"
12203         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12204                 skip_env "MDS doesn't support rename stats"
12205
12206         local testdir1=$DIR/${tdir}/stats_testdir1
12207         local testdir2=$DIR/${tdir}/stats_testdir2
12208         mkdir -p $DIR/${tdir}
12209
12210         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12211
12212         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12213         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12214
12215         createmany -o $testdir1/test 512 || error "createmany failed"
12216
12217         # check samedir rename size
12218         mv ${testdir1}/test0 ${testdir1}/test_0
12219
12220         local testdir1_size=$(ls -l $DIR/${tdir} |
12221                 awk '/stats_testdir1/ {print $5}')
12222         local testdir2_size=$(ls -l $DIR/${tdir} |
12223                 awk '/stats_testdir2/ {print $5}')
12224
12225         testdir1_size=$(order_2 $testdir1_size)
12226         testdir2_size=$(order_2 $testdir2_size)
12227
12228         testdir1_size=$(size_in_KMGT $testdir1_size)
12229         testdir2_size=$(size_in_KMGT $testdir2_size)
12230
12231         echo "source rename dir size: ${testdir1_size}"
12232         echo "target rename dir size: ${testdir2_size}"
12233
12234         local cmd="do_facet $SINGLEMDS $LCTL "
12235         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12236
12237         eval $cmd || error "$cmd failed"
12238         local samedir=$($cmd | grep 'same_dir')
12239         local same_sample=$(get_rename_size $testdir1_size)
12240         [ -z "$samedir" ] && error "samedir_rename_size count error"
12241         [[ $same_sample -eq 1 ]] ||
12242                 error "samedir_rename_size error $same_sample"
12243         echo "Check same dir rename stats success"
12244
12245         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12246
12247         # check crossdir rename size
12248         mv ${testdir1}/test_0 ${testdir2}/test_0
12249
12250         testdir1_size=$(ls -l $DIR/${tdir} |
12251                 awk '/stats_testdir1/ {print $5}')
12252         testdir2_size=$(ls -l $DIR/${tdir} |
12253                 awk '/stats_testdir2/ {print $5}')
12254
12255         testdir1_size=$(order_2 $testdir1_size)
12256         testdir2_size=$(order_2 $testdir2_size)
12257
12258         testdir1_size=$(size_in_KMGT $testdir1_size)
12259         testdir2_size=$(size_in_KMGT $testdir2_size)
12260
12261         echo "source rename dir size: ${testdir1_size}"
12262         echo "target rename dir size: ${testdir2_size}"
12263
12264         eval $cmd || error "$cmd failed"
12265         local crossdir=$($cmd | grep 'crossdir')
12266         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12267         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12268         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12269         [[ $src_sample -eq 1 ]] ||
12270                 error "crossdir_rename_size error $src_sample"
12271         [[ $tgt_sample -eq 1 ]] ||
12272                 error "crossdir_rename_size error $tgt_sample"
12273         echo "Check cross dir rename stats success"
12274         rm -rf $DIR/${tdir}
12275 }
12276 run_test 133d "Verifying rename_stats ========================================"
12277
12278 test_133e() {
12279         remote_mds_nodsh && skip "remote MDS with nodsh"
12280         remote_ost_nodsh && skip "remote OST with nodsh"
12281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12282
12283         local testdir=$DIR/${tdir}/stats_testdir
12284         local ctr f0 f1 bs=32768 count=42 sum
12285
12286         mkdir -p ${testdir} || error "mkdir failed"
12287
12288         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12289
12290         for ctr in {write,read}_bytes; do
12291                 sync
12292                 cancel_lru_locks osc
12293
12294                 do_facet ost1 $LCTL set_param -n \
12295                         "obdfilter.*.exports.clear=clear"
12296
12297                 if [ $ctr = write_bytes ]; then
12298                         f0=/dev/zero
12299                         f1=${testdir}/${tfile}
12300                 else
12301                         f0=${testdir}/${tfile}
12302                         f1=/dev/null
12303                 fi
12304
12305                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12306                         error "dd failed"
12307                 sync
12308                 cancel_lru_locks osc
12309
12310                 sum=$(do_facet ost1 $LCTL get_param \
12311                         "obdfilter.*.exports.*.stats" |
12312                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12313                                 $1 == ctr { sum += $7 }
12314                                 END { printf("%0.0f", sum) }')
12315
12316                 if ((sum != bs * count)); then
12317                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12318                 fi
12319         done
12320
12321         rm -rf $DIR/${tdir}
12322 }
12323 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
12324
12325 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
12326
12327 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
12328 # not honor the -ignore_readdir_race option correctly. So we call
12329 # error_ignore() rather than error() in these cases. See LU-11152.
12330 error_133() {
12331         if (find --version; do_facet mds1 find --version) |
12332                 grep -q '\b4\.5\.1[1-4]\b'; then
12333                 error_ignore LU-11152 "$@"
12334         else
12335                 error "$@"
12336         fi
12337 }
12338
12339 test_133f() {
12340         # First without trusting modes.
12341         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
12342         echo "proc_dirs='$proc_dirs'"
12343         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
12344         find $proc_dirs -exec cat '{}' \; &> /dev/null
12345
12346         # Second verifying readability.
12347         $LCTL get_param -R '*' &> /dev/null
12348
12349         # Verifing writability with badarea_io.
12350         find $proc_dirs \
12351                 -ignore_readdir_race \
12352                 -type f \
12353                 -not -name force_lbug \
12354                 -not -name changelog_mask \
12355                 -exec badarea_io '{}' \; ||
12356                         error_133 "find $proc_dirs failed"
12357 }
12358 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
12359
12360 test_133g() {
12361         remote_mds_nodsh && skip "remote MDS with nodsh"
12362         remote_ost_nodsh && skip "remote OST with nodsh"
12363
12364         # eventually, this can also be replaced with "lctl get_param -R",
12365         # but not until that option is always available on the server
12366         local facet
12367         for facet in mds1 ost1; do
12368                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
12369                         skip_noexit "Too old lustre on $facet"
12370                 local facet_proc_dirs=$(do_facet $facet \
12371                                         \\\ls -d $proc_regexp 2>/dev/null)
12372                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12373                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12374                 do_facet $facet find $facet_proc_dirs \
12375                         ! -name req_history \
12376                         -exec cat '{}' \\\; &> /dev/null
12377
12378                 do_facet $facet find $facet_proc_dirs \
12379                         ! -name req_history \
12380                         -type f \
12381                         -exec cat '{}' \\\; &> /dev/null ||
12382                                 error "proc file read failed"
12383
12384                 do_facet $facet find $facet_proc_dirs \
12385                         -ignore_readdir_race \
12386                         -type f \
12387                         -not -name force_lbug \
12388                         -not -name changelog_mask \
12389                         -exec badarea_io '{}' \\\; ||
12390                                 error_133 "$facet find $facet_proc_dirs failed"
12391         done
12392
12393         # remount the FS in case writes/reads /proc break the FS
12394         cleanup || error "failed to unmount"
12395         setup || error "failed to setup"
12396         true
12397 }
12398 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
12399
12400 test_133h() {
12401         remote_mds_nodsh && skip "remote MDS with nodsh"
12402         remote_ost_nodsh && skip "remote OST with nodsh"
12403         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
12404                 skip "Need MDS version at least 2.9.54"
12405
12406         local facet
12407
12408         for facet in client mds1 ost1; do
12409                 local facet_proc_dirs=$(do_facet $facet \
12410                                         \\\ls -d $proc_regexp 2> /dev/null)
12411                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12412                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12413                 # Get the list of files that are missing the terminating newline
12414                 local missing=($(do_facet $facet \
12415                         find ${facet_proc_dirs} -type f \|              \
12416                                 while read F\; do                       \
12417                                         awk -v FS='\v' -v RS='\v\v'     \
12418                                         "'END { if(NR>0 &&              \
12419                                         \\\$NF !~ /.*\\\n\$/)           \
12420                                                 print FILENAME}'"       \
12421                                         '\$F'\;                         \
12422                                 done 2>/dev/null))
12423                 [ ${#missing[*]} -eq 0 ] ||
12424                         error "files do not end with newline: ${missing[*]}"
12425         done
12426 }
12427 run_test 133h "Proc files should end with newlines"
12428
12429 test_134a() {
12430         remote_mds_nodsh && skip "remote MDS with nodsh"
12431         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12432                 skip "Need MDS version at least 2.7.54"
12433
12434         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12435         cancel_lru_locks mdc
12436
12437         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12438         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12439         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12440
12441         local nr=1000
12442         createmany -o $DIR/$tdir/f $nr ||
12443                 error "failed to create $nr files in $DIR/$tdir"
12444         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12445
12446         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12447         do_facet mds1 $LCTL set_param fail_loc=0x327
12448         do_facet mds1 $LCTL set_param fail_val=500
12449         touch $DIR/$tdir/m
12450
12451         echo "sleep 10 seconds ..."
12452         sleep 10
12453         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12454
12455         do_facet mds1 $LCTL set_param fail_loc=0
12456         do_facet mds1 $LCTL set_param fail_val=0
12457         [ $lck_cnt -lt $unused ] ||
12458                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
12459
12460         rm $DIR/$tdir/m
12461         unlinkmany $DIR/$tdir/f $nr
12462 }
12463 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
12464
12465 test_134b() {
12466         remote_mds_nodsh && skip "remote MDS with nodsh"
12467         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12468                 skip "Need MDS version at least 2.7.54"
12469
12470         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12471         cancel_lru_locks mdc
12472
12473         local low_wm=$(do_facet mds1 $LCTL get_param -n \
12474                         ldlm.lock_reclaim_threshold_mb)
12475         # disable reclaim temporarily
12476         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
12477
12478         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12479         do_facet mds1 $LCTL set_param fail_loc=0x328
12480         do_facet mds1 $LCTL set_param fail_val=500
12481
12482         $LCTL set_param debug=+trace
12483
12484         local nr=600
12485         createmany -o $DIR/$tdir/f $nr &
12486         local create_pid=$!
12487
12488         echo "Sleep $TIMEOUT seconds ..."
12489         sleep $TIMEOUT
12490         if ! ps -p $create_pid  > /dev/null 2>&1; then
12491                 do_facet mds1 $LCTL set_param fail_loc=0
12492                 do_facet mds1 $LCTL set_param fail_val=0
12493                 do_facet mds1 $LCTL set_param \
12494                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12495                 error "createmany finished incorrectly!"
12496         fi
12497         do_facet mds1 $LCTL set_param fail_loc=0
12498         do_facet mds1 $LCTL set_param fail_val=0
12499         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12500         wait $create_pid || return 1
12501
12502         unlinkmany $DIR/$tdir/f $nr
12503 }
12504 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12505
12506 test_140() { #bug-17379
12507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12508
12509         test_mkdir $DIR/$tdir
12510         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12511         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12512
12513         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12514         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12515         local i=0
12516         while i=$((i + 1)); do
12517                 test_mkdir $i
12518                 cd $i || error "Changing to $i"
12519                 ln -s ../stat stat || error "Creating stat symlink"
12520                 # Read the symlink until ELOOP present,
12521                 # not LBUGing the system is considered success,
12522                 # we didn't overrun the stack.
12523                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12524                 if [ $ret -ne 0 ]; then
12525                         if [ $ret -eq 40 ]; then
12526                                 break  # -ELOOP
12527                         else
12528                                 error "Open stat symlink"
12529                                         return
12530                         fi
12531                 fi
12532         done
12533         i=$((i - 1))
12534         echo "The symlink depth = $i"
12535         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12536                 error "Invalid symlink depth"
12537
12538         # Test recursive symlink
12539         ln -s symlink_self symlink_self
12540         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12541         echo "open symlink_self returns $ret"
12542         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12543 }
12544 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12545
12546 test_150() {
12547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12548
12549         local TF="$TMP/$tfile"
12550
12551         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12552         cp $TF $DIR/$tfile
12553         cancel_lru_locks $OSC
12554         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12555         remount_client $MOUNT
12556         df -P $MOUNT
12557         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12558
12559         $TRUNCATE $TF 6000
12560         $TRUNCATE $DIR/$tfile 6000
12561         cancel_lru_locks $OSC
12562         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12563
12564         echo "12345" >>$TF
12565         echo "12345" >>$DIR/$tfile
12566         cancel_lru_locks $OSC
12567         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12568
12569         echo "12345" >>$TF
12570         echo "12345" >>$DIR/$tfile
12571         cancel_lru_locks $OSC
12572         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12573
12574         rm -f $TF
12575         true
12576 }
12577 run_test 150 "truncate/append tests"
12578
12579 #LU-2902 roc_hit was not able to read all values from lproc
12580 function roc_hit_init() {
12581         local list=$(comma_list $(osts_nodes))
12582         local dir=$DIR/$tdir-check
12583         local file=$dir/$tfile
12584         local BEFORE
12585         local AFTER
12586         local idx
12587
12588         test_mkdir $dir
12589         #use setstripe to do a write to every ost
12590         for i in $(seq 0 $((OSTCOUNT-1))); do
12591                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12592                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12593                 idx=$(printf %04x $i)
12594                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12595                         awk '$1 == "cache_access" {sum += $7}
12596                                 END { printf("%0.0f", sum) }')
12597
12598                 cancel_lru_locks osc
12599                 cat $file >/dev/null
12600
12601                 AFTER=$(get_osd_param $list *OST*$idx stats |
12602                         awk '$1 == "cache_access" {sum += $7}
12603                                 END { printf("%0.0f", sum) }')
12604
12605                 echo BEFORE:$BEFORE AFTER:$AFTER
12606                 if ! let "AFTER - BEFORE == 4"; then
12607                         rm -rf $dir
12608                         error "roc_hit is not safe to use"
12609                 fi
12610                 rm $file
12611         done
12612
12613         rm -rf $dir
12614 }
12615
12616 function roc_hit() {
12617         local list=$(comma_list $(osts_nodes))
12618         echo $(get_osd_param $list '' stats |
12619                 awk '$1 == "cache_hit" {sum += $7}
12620                         END { printf("%0.0f", sum) }')
12621 }
12622
12623 function set_cache() {
12624         local on=1
12625
12626         if [ "$2" == "off" ]; then
12627                 on=0;
12628         fi
12629         local list=$(comma_list $(osts_nodes))
12630         set_osd_param $list '' $1_cache_enable $on
12631
12632         cancel_lru_locks osc
12633 }
12634
12635 test_151() {
12636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12637         remote_ost_nodsh && skip "remote OST with nodsh"
12638
12639         local CPAGES=3
12640         local list=$(comma_list $(osts_nodes))
12641
12642         # check whether obdfilter is cache capable at all
12643         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12644                 skip "not cache-capable obdfilter"
12645         fi
12646
12647         # check cache is enabled on all obdfilters
12648         if get_osd_param $list '' read_cache_enable | grep 0; then
12649                 skip "oss cache is disabled"
12650         fi
12651
12652         set_osd_param $list '' writethrough_cache_enable 1
12653
12654         # check write cache is enabled on all obdfilters
12655         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12656                 skip "oss write cache is NOT enabled"
12657         fi
12658
12659         roc_hit_init
12660
12661         #define OBD_FAIL_OBD_NO_LRU  0x609
12662         do_nodes $list $LCTL set_param fail_loc=0x609
12663
12664         # pages should be in the case right after write
12665         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12666                 error "dd failed"
12667
12668         local BEFORE=$(roc_hit)
12669         cancel_lru_locks osc
12670         cat $DIR/$tfile >/dev/null
12671         local AFTER=$(roc_hit)
12672
12673         do_nodes $list $LCTL set_param fail_loc=0
12674
12675         if ! let "AFTER - BEFORE == CPAGES"; then
12676                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12677         fi
12678
12679         # the following read invalidates the cache
12680         cancel_lru_locks osc
12681         set_osd_param $list '' read_cache_enable 0
12682         cat $DIR/$tfile >/dev/null
12683
12684         # now data shouldn't be found in the cache
12685         BEFORE=$(roc_hit)
12686         cancel_lru_locks osc
12687         cat $DIR/$tfile >/dev/null
12688         AFTER=$(roc_hit)
12689         if let "AFTER - BEFORE != 0"; then
12690                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12691         fi
12692
12693         set_osd_param $list '' read_cache_enable 1
12694         rm -f $DIR/$tfile
12695 }
12696 run_test 151 "test cache on oss and controls ==============================="
12697
12698 test_152() {
12699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12700
12701         local TF="$TMP/$tfile"
12702
12703         # simulate ENOMEM during write
12704 #define OBD_FAIL_OST_NOMEM      0x226
12705         lctl set_param fail_loc=0x80000226
12706         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12707         cp $TF $DIR/$tfile
12708         sync || error "sync failed"
12709         lctl set_param fail_loc=0
12710
12711         # discard client's cache
12712         cancel_lru_locks osc
12713
12714         # simulate ENOMEM during read
12715         lctl set_param fail_loc=0x80000226
12716         cmp $TF $DIR/$tfile || error "cmp failed"
12717         lctl set_param fail_loc=0
12718
12719         rm -f $TF
12720 }
12721 run_test 152 "test read/write with enomem ============================"
12722
12723 test_153() {
12724         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12725 }
12726 run_test 153 "test if fdatasync does not crash ======================="
12727
12728 dot_lustre_fid_permission_check() {
12729         local fid=$1
12730         local ffid=$MOUNT/.lustre/fid/$fid
12731         local test_dir=$2
12732
12733         echo "stat fid $fid"
12734         stat $ffid > /dev/null || error "stat $ffid failed."
12735         echo "touch fid $fid"
12736         touch $ffid || error "touch $ffid failed."
12737         echo "write to fid $fid"
12738         cat /etc/hosts > $ffid || error "write $ffid failed."
12739         echo "read fid $fid"
12740         diff /etc/hosts $ffid || error "read $ffid failed."
12741         echo "append write to fid $fid"
12742         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12743         echo "rename fid $fid"
12744         mv $ffid $test_dir/$tfile.1 &&
12745                 error "rename $ffid to $tfile.1 should fail."
12746         touch $test_dir/$tfile.1
12747         mv $test_dir/$tfile.1 $ffid &&
12748                 error "rename $tfile.1 to $ffid should fail."
12749         rm -f $test_dir/$tfile.1
12750         echo "truncate fid $fid"
12751         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12752         echo "link fid $fid"
12753         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12754         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12755                 echo "setfacl fid $fid"
12756                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12757                 echo "getfacl fid $fid"
12758                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12759         fi
12760         echo "unlink fid $fid"
12761         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12762         echo "mknod fid $fid"
12763         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12764
12765         fid=[0xf00000400:0x1:0x0]
12766         ffid=$MOUNT/.lustre/fid/$fid
12767
12768         echo "stat non-exist fid $fid"
12769         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12770         echo "write to non-exist fid $fid"
12771         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12772         echo "link new fid $fid"
12773         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12774
12775         mkdir -p $test_dir/$tdir
12776         touch $test_dir/$tdir/$tfile
12777         fid=$($LFS path2fid $test_dir/$tdir)
12778         rc=$?
12779         [ $rc -ne 0 ] &&
12780                 error "error: could not get fid for $test_dir/$dir/$tfile."
12781
12782         ffid=$MOUNT/.lustre/fid/$fid
12783
12784         echo "ls $fid"
12785         ls $ffid > /dev/null || error "ls $ffid failed."
12786         echo "touch $fid/$tfile.1"
12787         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12788
12789         echo "touch $MOUNT/.lustre/fid/$tfile"
12790         touch $MOUNT/.lustre/fid/$tfile && \
12791                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12792
12793         echo "setxattr to $MOUNT/.lustre/fid"
12794         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12795
12796         echo "listxattr for $MOUNT/.lustre/fid"
12797         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12798
12799         echo "delxattr from $MOUNT/.lustre/fid"
12800         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12801
12802         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12803         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12804                 error "touch invalid fid should fail."
12805
12806         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12807         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12808                 error "touch non-normal fid should fail."
12809
12810         echo "rename $tdir to $MOUNT/.lustre/fid"
12811         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12812                 error "rename to $MOUNT/.lustre/fid should fail."
12813
12814         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12815         then            # LU-3547
12816                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12817                 local new_obf_mode=777
12818
12819                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12820                 chmod $new_obf_mode $DIR/.lustre/fid ||
12821                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12822
12823                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12824                 [ $obf_mode -eq $new_obf_mode ] ||
12825                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12826
12827                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12828                 chmod $old_obf_mode $DIR/.lustre/fid ||
12829                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12830         fi
12831
12832         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12833         fid=$($LFS path2fid $test_dir/$tfile-2)
12834
12835         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12836         then # LU-5424
12837                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12838                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12839                         error "create lov data thru .lustre failed"
12840         fi
12841         echo "cp /etc/passwd $test_dir/$tfile-2"
12842         cp /etc/passwd $test_dir/$tfile-2 ||
12843                 error "copy to $test_dir/$tfile-2 failed."
12844         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12845         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12846                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12847
12848         rm -rf $test_dir/tfile.lnk
12849         rm -rf $test_dir/$tfile-2
12850 }
12851
12852 test_154A() {
12853         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12854                 skip "Need MDS version at least 2.4.1"
12855
12856         local tf=$DIR/$tfile
12857         touch $tf
12858
12859         local fid=$($LFS path2fid $tf)
12860         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12861
12862         # check that we get the same pathname back
12863         local found=$($LFS fid2path $MOUNT "$fid")
12864         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12865         [ "$found" == "$tf" ] ||
12866                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12867 }
12868 run_test 154A "lfs path2fid and fid2path basic checks"
12869
12870 test_154B() {
12871         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12872                 skip "Need MDS version at least 2.4.1"
12873
12874         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12875         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12876         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12877         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12878
12879         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12880         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12881
12882         # check that we get the same pathname
12883         echo "PFID: $PFID, name: $name"
12884         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12885         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12886         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12887                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12888
12889         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12890 }
12891 run_test 154B "verify the ll_decode_linkea tool"
12892
12893 test_154a() {
12894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12895         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12896         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12897                 skip "Need MDS version at least 2.2.51"
12898         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12899
12900         cp /etc/hosts $DIR/$tfile
12901
12902         fid=$($LFS path2fid $DIR/$tfile)
12903         rc=$?
12904         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
12905
12906         dot_lustre_fid_permission_check "$fid" $DIR ||
12907                 error "dot lustre permission check $fid failed"
12908
12909         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
12910
12911         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
12912
12913         touch $MOUNT/.lustre/file &&
12914                 error "creation is not allowed under .lustre"
12915
12916         mkdir $MOUNT/.lustre/dir &&
12917                 error "mkdir is not allowed under .lustre"
12918
12919         rm -rf $DIR/$tfile
12920 }
12921 run_test 154a "Open-by-FID"
12922
12923 test_154b() {
12924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12925         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12926         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12927         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12928                 skip "Need MDS version at least 2.2.51"
12929
12930         local remote_dir=$DIR/$tdir/remote_dir
12931         local MDTIDX=1
12932         local rc=0
12933
12934         mkdir -p $DIR/$tdir
12935         $LFS mkdir -i $MDTIDX $remote_dir ||
12936                 error "create remote directory failed"
12937
12938         cp /etc/hosts $remote_dir/$tfile
12939
12940         fid=$($LFS path2fid $remote_dir/$tfile)
12941         rc=$?
12942         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
12943
12944         dot_lustre_fid_permission_check "$fid" $remote_dir ||
12945                 error "dot lustre permission check $fid failed"
12946         rm -rf $DIR/$tdir
12947 }
12948 run_test 154b "Open-by-FID for remote directory"
12949
12950 test_154c() {
12951         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12952                 skip "Need MDS version at least 2.4.1"
12953
12954         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
12955         local FID1=$($LFS path2fid $DIR/$tfile.1)
12956         local FID2=$($LFS path2fid $DIR/$tfile.2)
12957         local FID3=$($LFS path2fid $DIR/$tfile.3)
12958
12959         local N=1
12960         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
12961                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
12962                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
12963                 local want=FID$N
12964                 [ "$FID" = "${!want}" ] ||
12965                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
12966                 N=$((N + 1))
12967         done
12968
12969         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
12970         do
12971                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
12972                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
12973                 N=$((N + 1))
12974         done
12975 }
12976 run_test 154c "lfs path2fid and fid2path multiple arguments"
12977
12978 test_154d() {
12979         remote_mds_nodsh && skip "remote MDS with nodsh"
12980         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
12981                 skip "Need MDS version at least 2.5.53"
12982
12983         if remote_mds; then
12984                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
12985         else
12986                 nid="0@lo"
12987         fi
12988         local proc_ofile="mdt.*.exports.'$nid'.open_files"
12989         local fd
12990         local cmd
12991
12992         rm -f $DIR/$tfile
12993         touch $DIR/$tfile
12994
12995         local fid=$($LFS path2fid $DIR/$tfile)
12996         # Open the file
12997         fd=$(free_fd)
12998         cmd="exec $fd<$DIR/$tfile"
12999         eval $cmd
13000         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13001         echo "$fid_list" | grep "$fid"
13002         rc=$?
13003
13004         cmd="exec $fd>/dev/null"
13005         eval $cmd
13006         if [ $rc -ne 0 ]; then
13007                 error "FID $fid not found in open files list $fid_list"
13008         fi
13009 }
13010 run_test 154d "Verify open file fid"
13011
13012 test_154e()
13013 {
13014         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13015                 skip "Need MDS version at least 2.6.50"
13016
13017         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13018                 error ".lustre returned by readdir"
13019         fi
13020 }
13021 run_test 154e ".lustre is not returned by readdir"
13022
13023 test_154f() {
13024         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13025
13026         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13027         test_mkdir -p -c1 $DIR/$tdir/d
13028         # test dirs inherit from its stripe
13029         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13030         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13031         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13032         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13033         touch $DIR/f
13034
13035         # get fid of parents
13036         local FID0=$($LFS path2fid $DIR/$tdir/d)
13037         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13038         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13039         local FID3=$($LFS path2fid $DIR)
13040
13041         # check that path2fid --parents returns expected <parent_fid>/name
13042         # 1) test for a directory (single parent)
13043         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13044         [ "$parent" == "$FID0/foo1" ] ||
13045                 error "expected parent: $FID0/foo1, got: $parent"
13046
13047         # 2) test for a file with nlink > 1 (multiple parents)
13048         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13049         echo "$parent" | grep -F "$FID1/$tfile" ||
13050                 error "$FID1/$tfile not returned in parent list"
13051         echo "$parent" | grep -F "$FID2/link" ||
13052                 error "$FID2/link not returned in parent list"
13053
13054         # 3) get parent by fid
13055         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13056         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13057         echo "$parent" | grep -F "$FID1/$tfile" ||
13058                 error "$FID1/$tfile not returned in parent list (by fid)"
13059         echo "$parent" | grep -F "$FID2/link" ||
13060                 error "$FID2/link not returned in parent list (by fid)"
13061
13062         # 4) test for entry in root directory
13063         parent=$($LFS path2fid --parents $DIR/f)
13064         echo "$parent" | grep -F "$FID3/f" ||
13065                 error "$FID3/f not returned in parent list"
13066
13067         # 5) test it on root directory
13068         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13069                 error "$MOUNT should not have parents"
13070
13071         # enable xattr caching and check that linkea is correctly updated
13072         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13073         save_lustre_params client "llite.*.xattr_cache" > $save
13074         lctl set_param llite.*.xattr_cache 1
13075
13076         # 6.1) linkea update on rename
13077         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13078
13079         # get parents by fid
13080         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13081         # foo1 should no longer be returned in parent list
13082         echo "$parent" | grep -F "$FID1" &&
13083                 error "$FID1 should no longer be in parent list"
13084         # the new path should appear
13085         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13086                 error "$FID2/$tfile.moved is not in parent list"
13087
13088         # 6.2) linkea update on unlink
13089         rm -f $DIR/$tdir/d/foo2/link
13090         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13091         # foo2/link should no longer be returned in parent list
13092         echo "$parent" | grep -F "$FID2/link" &&
13093                 error "$FID2/link should no longer be in parent list"
13094         true
13095
13096         rm -f $DIR/f
13097         restore_lustre_params < $save
13098         rm -f $save
13099 }
13100 run_test 154f "get parent fids by reading link ea"
13101
13102 test_154g()
13103 {
13104         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13105         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13106            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13107                 skip "Need MDS version at least 2.6.92"
13108
13109         mkdir -p $DIR/$tdir
13110         llapi_fid_test -d $DIR/$tdir
13111 }
13112 run_test 154g "various llapi FID tests"
13113
13114 test_155_small_load() {
13115     local temp=$TMP/$tfile
13116     local file=$DIR/$tfile
13117
13118     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13119         error "dd of=$temp bs=6096 count=1 failed"
13120     cp $temp $file
13121     cancel_lru_locks $OSC
13122     cmp $temp $file || error "$temp $file differ"
13123
13124     $TRUNCATE $temp 6000
13125     $TRUNCATE $file 6000
13126     cmp $temp $file || error "$temp $file differ (truncate1)"
13127
13128     echo "12345" >>$temp
13129     echo "12345" >>$file
13130     cmp $temp $file || error "$temp $file differ (append1)"
13131
13132     echo "12345" >>$temp
13133     echo "12345" >>$file
13134     cmp $temp $file || error "$temp $file differ (append2)"
13135
13136     rm -f $temp $file
13137     true
13138 }
13139
13140 test_155_big_load() {
13141         remote_ost_nodsh && skip "remote OST with nodsh"
13142
13143         local temp=$TMP/$tfile
13144         local file=$DIR/$tfile
13145
13146         free_min_max
13147         local cache_size=$(do_facet ost$((MAXI+1)) \
13148                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13149         local large_file_size=$((cache_size * 2))
13150
13151         echo "OSS cache size: $cache_size KB"
13152         echo "Large file size: $large_file_size KB"
13153
13154         [ $MAXV -le $large_file_size ] &&
13155                 skip_env "max available OST size needs > $large_file_size KB"
13156
13157         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13158
13159         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13160                 error "dd of=$temp bs=$large_file_size count=1k failed"
13161         cp $temp $file
13162         ls -lh $temp $file
13163         cancel_lru_locks osc
13164         cmp $temp $file || error "$temp $file differ"
13165
13166         rm -f $temp $file
13167         true
13168 }
13169
13170 save_writethrough() {
13171         local facets=$(get_facets OST)
13172
13173         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13174 }
13175
13176 test_155a() {
13177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13178
13179         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13180
13181         save_writethrough $p
13182
13183         set_cache read on
13184         set_cache writethrough on
13185         test_155_small_load
13186         restore_lustre_params < $p
13187         rm -f $p
13188 }
13189 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13190
13191 test_155b() {
13192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13193
13194         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13195
13196         save_writethrough $p
13197
13198         set_cache read on
13199         set_cache writethrough off
13200         test_155_small_load
13201         restore_lustre_params < $p
13202         rm -f $p
13203 }
13204 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13205
13206 test_155c() {
13207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13208
13209         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13210
13211         save_writethrough $p
13212
13213         set_cache read off
13214         set_cache writethrough on
13215         test_155_small_load
13216         restore_lustre_params < $p
13217         rm -f $p
13218 }
13219 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13220
13221 test_155d() {
13222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13223
13224         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13225
13226         save_writethrough $p
13227
13228         set_cache read off
13229         set_cache writethrough off
13230         test_155_small_load
13231         restore_lustre_params < $p
13232         rm -f $p
13233 }
13234 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
13235
13236 test_155e() {
13237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13238
13239         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13240
13241         save_writethrough $p
13242
13243         set_cache read on
13244         set_cache writethrough on
13245         test_155_big_load
13246         restore_lustre_params < $p
13247         rm -f $p
13248 }
13249 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
13250
13251 test_155f() {
13252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13253
13254         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13255
13256         save_writethrough $p
13257
13258         set_cache read on
13259         set_cache writethrough off
13260         test_155_big_load
13261         restore_lustre_params < $p
13262         rm -f $p
13263 }
13264 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
13265
13266 test_155g() {
13267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13268
13269         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13270
13271         save_writethrough $p
13272
13273         set_cache read off
13274         set_cache writethrough on
13275         test_155_big_load
13276         restore_lustre_params < $p
13277         rm -f $p
13278 }
13279 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
13280
13281 test_155h() {
13282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13283
13284         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13285
13286         save_writethrough $p
13287
13288         set_cache read off
13289         set_cache writethrough off
13290         test_155_big_load
13291         restore_lustre_params < $p
13292         rm -f $p
13293 }
13294 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
13295
13296 test_156() {
13297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13298         remote_ost_nodsh && skip "remote OST with nodsh"
13299         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
13300                 skip "stats not implemented on old servers"
13301         [ "$ost1_FSTYPE" = "zfs" ] &&
13302                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
13303
13304         local CPAGES=3
13305         local BEFORE
13306         local AFTER
13307         local file="$DIR/$tfile"
13308         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13309
13310         save_writethrough $p
13311         roc_hit_init
13312
13313         log "Turn on read and write cache"
13314         set_cache read on
13315         set_cache writethrough on
13316
13317         log "Write data and read it back."
13318         log "Read should be satisfied from the cache."
13319         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13320         BEFORE=$(roc_hit)
13321         cancel_lru_locks osc
13322         cat $file >/dev/null
13323         AFTER=$(roc_hit)
13324         if ! let "AFTER - BEFORE == CPAGES"; then
13325                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13326         else
13327                 log "cache hits:: before: $BEFORE, after: $AFTER"
13328         fi
13329
13330         log "Read again; it should be satisfied from the cache."
13331         BEFORE=$AFTER
13332         cancel_lru_locks osc
13333         cat $file >/dev/null
13334         AFTER=$(roc_hit)
13335         if ! let "AFTER - BEFORE == CPAGES"; then
13336                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13337         else
13338                 log "cache hits:: before: $BEFORE, after: $AFTER"
13339         fi
13340
13341         log "Turn off the read cache and turn on the write cache"
13342         set_cache read off
13343         set_cache writethrough on
13344
13345         log "Read again; it should be satisfied from the cache."
13346         BEFORE=$(roc_hit)
13347         cancel_lru_locks osc
13348         cat $file >/dev/null
13349         AFTER=$(roc_hit)
13350         if ! let "AFTER - BEFORE == CPAGES"; then
13351                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13352         else
13353                 log "cache hits:: before: $BEFORE, after: $AFTER"
13354         fi
13355
13356         log "Read again; it should not be satisfied from the cache."
13357         BEFORE=$AFTER
13358         cancel_lru_locks osc
13359         cat $file >/dev/null
13360         AFTER=$(roc_hit)
13361         if ! let "AFTER - BEFORE == 0"; then
13362                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13363         else
13364                 log "cache hits:: before: $BEFORE, after: $AFTER"
13365         fi
13366
13367         log "Write data and read it back."
13368         log "Read should be satisfied from the cache."
13369         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13370         BEFORE=$(roc_hit)
13371         cancel_lru_locks osc
13372         cat $file >/dev/null
13373         AFTER=$(roc_hit)
13374         if ! let "AFTER - BEFORE == CPAGES"; then
13375                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13376         else
13377                 log "cache hits:: before: $BEFORE, after: $AFTER"
13378         fi
13379
13380         log "Read again; it should not be satisfied from the cache."
13381         BEFORE=$AFTER
13382         cancel_lru_locks osc
13383         cat $file >/dev/null
13384         AFTER=$(roc_hit)
13385         if ! let "AFTER - BEFORE == 0"; then
13386                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13387         else
13388                 log "cache hits:: before: $BEFORE, after: $AFTER"
13389         fi
13390
13391         log "Turn off read and write cache"
13392         set_cache read off
13393         set_cache writethrough off
13394
13395         log "Write data and read it back"
13396         log "It should not be satisfied from the cache."
13397         rm -f $file
13398         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13399         cancel_lru_locks osc
13400         BEFORE=$(roc_hit)
13401         cat $file >/dev/null
13402         AFTER=$(roc_hit)
13403         if ! let "AFTER - BEFORE == 0"; then
13404                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
13405         else
13406                 log "cache hits:: before: $BEFORE, after: $AFTER"
13407         fi
13408
13409         log "Turn on the read cache and turn off the write cache"
13410         set_cache read on
13411         set_cache writethrough off
13412
13413         log "Write data and read it back"
13414         log "It should not be satisfied from the cache."
13415         rm -f $file
13416         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13417         BEFORE=$(roc_hit)
13418         cancel_lru_locks osc
13419         cat $file >/dev/null
13420         AFTER=$(roc_hit)
13421         if ! let "AFTER - BEFORE == 0"; then
13422                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
13423         else
13424                 log "cache hits:: before: $BEFORE, after: $AFTER"
13425         fi
13426
13427         log "Read again; it should be satisfied from the cache."
13428         BEFORE=$(roc_hit)
13429         cancel_lru_locks osc
13430         cat $file >/dev/null
13431         AFTER=$(roc_hit)
13432         if ! let "AFTER - BEFORE == CPAGES"; then
13433                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13434         else
13435                 log "cache hits:: before: $BEFORE, after: $AFTER"
13436         fi
13437
13438         restore_lustre_params < $p
13439         rm -f $p $file
13440 }
13441 run_test 156 "Verification of tunables"
13442
13443 test_160a() {
13444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13445         remote_mds_nodsh && skip "remote MDS with nodsh"
13446         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13447                 skip "Need MDS version at least 2.2.0"
13448
13449         changelog_register || error "changelog_register failed"
13450         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13451         changelog_users $SINGLEMDS | grep -q $cl_user ||
13452                 error "User $cl_user not found in changelog_users"
13453
13454         # change something
13455         test_mkdir -p $DIR/$tdir/pics/2008/zachy
13456         changelog_clear 0 || error "changelog_clear failed"
13457         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
13458         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
13459         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
13460         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
13461         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
13462         rm $DIR/$tdir/pics/desktop.jpg
13463
13464         changelog_dump | tail -10
13465
13466         echo "verifying changelog mask"
13467         changelog_chmask "-MKDIR"
13468         changelog_chmask "-CLOSE"
13469
13470         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
13471         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
13472
13473         changelog_chmask "+MKDIR"
13474         changelog_chmask "+CLOSE"
13475
13476         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
13477         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13478
13479         changelog_dump | tail -10
13480         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13481         CLOSES=$(changelog_dump | grep -c "CLOSE")
13482         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13483         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13484
13485         # verify contents
13486         echo "verifying target fid"
13487         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13488         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13489         [ "$fidc" == "$fidf" ] ||
13490                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13491         echo "verifying parent fid"
13492         # The FID returned from the Changelog may be the directory shard on
13493         # a different MDT, and not the FID returned by path2fid on the parent.
13494         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13495         # since this is what will matter when recreating this file in the tree.
13496         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13497         local pathp=$($LFS fid2path $MOUNT "$fidp")
13498         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13499                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13500
13501         echo "getting records for $cl_user"
13502         changelog_users $SINGLEMDS
13503         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13504         local nclr=3
13505         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13506                 error "changelog_clear failed"
13507         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13508         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13509         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13510                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13511
13512         local min0_rec=$(changelog_users $SINGLEMDS |
13513                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13514         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13515                           awk '{ print $1; exit; }')
13516
13517         changelog_dump | tail -n 5
13518         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13519         [ $first_rec == $((min0_rec + 1)) ] ||
13520                 error "first index should be $min0_rec + 1 not $first_rec"
13521
13522         # LU-3446 changelog index reset on MDT restart
13523         local cur_rec1=$(changelog_users $SINGLEMDS |
13524                          awk '/^current.index:/ { print $NF }')
13525         changelog_clear 0 ||
13526                 error "clear all changelog records for $cl_user failed"
13527         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13528         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13529                 error "Fail to start $SINGLEMDS"
13530         local cur_rec2=$(changelog_users $SINGLEMDS |
13531                          awk '/^current.index:/ { print $NF }')
13532         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13533         [ $cur_rec1 == $cur_rec2 ] ||
13534                 error "current index should be $cur_rec1 not $cur_rec2"
13535
13536         echo "verifying users from this test are deregistered"
13537         changelog_deregister || error "changelog_deregister failed"
13538         changelog_users $SINGLEMDS | grep -q $cl_user &&
13539                 error "User '$cl_user' still in changelog_users"
13540
13541         # lctl get_param -n mdd.*.changelog_users
13542         # current index: 144
13543         # ID    index (idle seconds)
13544         # cl3   144 (2)
13545         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13546                 # this is the normal case where all users were deregistered
13547                 # make sure no new records are added when no users are present
13548                 local last_rec1=$(changelog_users $SINGLEMDS |
13549                                   awk '/^current.index:/ { print $NF }')
13550                 touch $DIR/$tdir/chloe
13551                 local last_rec2=$(changelog_users $SINGLEMDS |
13552                                   awk '/^current.index:/ { print $NF }')
13553                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13554                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13555         else
13556                 # any changelog users must be leftovers from a previous test
13557                 changelog_users $SINGLEMDS
13558                 echo "other changelog users; can't verify off"
13559         fi
13560 }
13561 run_test 160a "changelog sanity"
13562
13563 test_160b() { # LU-3587
13564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13565         remote_mds_nodsh && skip "remote MDS with nodsh"
13566         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13567                 skip "Need MDS version at least 2.2.0"
13568
13569         changelog_register || error "changelog_register failed"
13570         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13571         changelog_users $SINGLEMDS | grep -q $cl_user ||
13572                 error "User '$cl_user' not found in changelog_users"
13573
13574         local longname1=$(str_repeat a 255)
13575         local longname2=$(str_repeat b 255)
13576
13577         cd $DIR
13578         echo "creating very long named file"
13579         touch $longname1 || error "create of '$longname1' failed"
13580         echo "renaming very long named file"
13581         mv $longname1 $longname2
13582
13583         changelog_dump | grep RENME | tail -n 5
13584         rm -f $longname2
13585 }
13586 run_test 160b "Verify that very long rename doesn't crash in changelog"
13587
13588 test_160c() {
13589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13590         remote_mds_nodsh && skip "remote MDS with nodsh"
13591
13592         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13593                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13594                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13595                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13596
13597         local rc=0
13598
13599         # Registration step
13600         changelog_register || error "changelog_register failed"
13601
13602         rm -rf $DIR/$tdir
13603         mkdir -p $DIR/$tdir
13604         $MCREATE $DIR/$tdir/foo_160c
13605         changelog_chmask "-TRUNC"
13606         $TRUNCATE $DIR/$tdir/foo_160c 200
13607         changelog_chmask "+TRUNC"
13608         $TRUNCATE $DIR/$tdir/foo_160c 199
13609         changelog_dump | tail -n 5
13610         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13611         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13612 }
13613 run_test 160c "verify that changelog log catch the truncate event"
13614
13615 test_160d() {
13616         remote_mds_nodsh && skip "remote MDS with nodsh"
13617         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13619         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13620                 skip "Need MDS version at least 2.7.60"
13621
13622         # Registration step
13623         changelog_register || error "changelog_register failed"
13624
13625         mkdir -p $DIR/$tdir/migrate_dir
13626         changelog_clear 0 || error "changelog_clear failed"
13627
13628         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13629         changelog_dump | tail -n 5
13630         local migrates=$(changelog_dump | grep -c "MIGRT")
13631         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13632 }
13633 run_test 160d "verify that changelog log catch the migrate event"
13634
13635 test_160e() {
13636         remote_mds_nodsh && skip "remote MDS with nodsh"
13637
13638         # Create a user
13639         changelog_register || error "changelog_register failed"
13640
13641         # Delete a future user (expect fail)
13642         local MDT0=$(facet_svc $SINGLEMDS)
13643         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13644         local rc=$?
13645
13646         if [ $rc -eq 0 ]; then
13647                 error "Deleted non-existant user cl77"
13648         elif [ $rc -ne 2 ]; then
13649                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13650         fi
13651
13652         # Clear to a bad index (1 billion should be safe)
13653         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13654         rc=$?
13655
13656         if [ $rc -eq 0 ]; then
13657                 error "Successfully cleared to invalid CL index"
13658         elif [ $rc -ne 22 ]; then
13659                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13660         fi
13661 }
13662 run_test 160e "changelog negative testing (should return errors)"
13663
13664 test_160f() {
13665         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13666         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13667                 skip "Need MDS version at least 2.10.56"
13668
13669         local mdts=$(comma_list $(mdts_nodes))
13670
13671         # Create a user
13672         changelog_register || error "first changelog_register failed"
13673         changelog_register || error "second changelog_register failed"
13674         local cl_users
13675         declare -A cl_user1
13676         declare -A cl_user2
13677         local user_rec1
13678         local user_rec2
13679         local i
13680
13681         # generate some changelog records to accumulate on each MDT
13682         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13683         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13684                 error "create $DIR/$tdir/$tfile failed"
13685
13686         # check changelogs have been generated
13687         local nbcl=$(changelog_dump | wc -l)
13688         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13689
13690         for param in "changelog_max_idle_time=10" \
13691                      "changelog_gc=1" \
13692                      "changelog_min_gc_interval=2" \
13693                      "changelog_min_free_cat_entries=3"; do
13694                 local MDT0=$(facet_svc $SINGLEMDS)
13695                 local var="${param%=*}"
13696                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13697
13698                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13699                 do_nodes $mdts $LCTL set_param mdd.*.$param
13700         done
13701
13702         # force cl_user2 to be idle (1st part)
13703         sleep 9
13704
13705         # simulate changelog catalog almost full
13706         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13707         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13708
13709         for i in $(seq $MDSCOUNT); do
13710                 cl_users=(${CL_USERS[mds$i]})
13711                 cl_user1[mds$i]="${cl_users[0]}"
13712                 cl_user2[mds$i]="${cl_users[1]}"
13713
13714                 [ -n "${cl_user1[mds$i]}" ] ||
13715                         error "mds$i: no user registered"
13716                 [ -n "${cl_user2[mds$i]}" ] ||
13717                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13718
13719                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13720                 [ -n "$user_rec1" ] ||
13721                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13722                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13723                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13724                 [ -n "$user_rec2" ] ||
13725                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13726                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13727                      "$user_rec1 + 2 == $user_rec2"
13728                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13729                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13730                               "$user_rec1 + 2, but is $user_rec2"
13731                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13732                 [ -n "$user_rec2" ] ||
13733                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13734                 [ $user_rec1 == $user_rec2 ] ||
13735                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13736                               "$user_rec1, but is $user_rec2"
13737         done
13738
13739         # force cl_user2 to be idle (2nd part) and to reach
13740         # changelog_max_idle_time
13741         sleep 2
13742
13743         # generate one more changelog to trigger fail_loc
13744         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13745                 error "create $DIR/$tdir/${tfile}bis failed"
13746
13747         # ensure gc thread is done
13748         for i in $(mdts_nodes); do
13749                 wait_update $i \
13750                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13751                         error "$i: GC-thread not done"
13752         done
13753
13754         local first_rec
13755         for i in $(seq $MDSCOUNT); do
13756                 # check cl_user1 still registered
13757                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13758                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13759                 # check cl_user2 unregistered
13760                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13761                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13762
13763                 # check changelogs are present and starting at $user_rec1 + 1
13764                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13765                 [ -n "$user_rec1" ] ||
13766                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13767                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13768                             awk '{ print $1; exit; }')
13769
13770                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13771                 [ $((user_rec1 + 1)) == $first_rec ] ||
13772                         error "mds$i: first index should be $user_rec1 + 1, " \
13773                               "but is $first_rec"
13774         done
13775 }
13776 run_test 160f "changelog garbage collect (timestamped users)"
13777
13778 test_160g() {
13779         remote_mds_nodsh && skip "remote MDS with nodsh"
13780         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13781                 skip "Need MDS version at least 2.10.56"
13782
13783         local mdts=$(comma_list $(mdts_nodes))
13784
13785         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13786         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13787
13788         # Create a user
13789         changelog_register || error "first changelog_register failed"
13790         changelog_register || error "second changelog_register failed"
13791         local cl_users
13792         declare -A cl_user1
13793         declare -A cl_user2
13794         local user_rec1
13795         local user_rec2
13796         local i
13797
13798         # generate some changelog records to accumulate on each MDT
13799         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13800         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13801                 error "create $DIR/$tdir/$tfile failed"
13802
13803         # check changelogs have been generated
13804         local nbcl=$(changelog_dump | wc -l)
13805         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13806
13807         # reduce the max_idle_indexes value to make sure we exceed it
13808         max_ndx=$((nbcl / 2 - 1))
13809
13810         for param in "changelog_max_idle_indexes=$max_ndx" \
13811                      "changelog_gc=1" \
13812                      "changelog_min_gc_interval=2" \
13813                      "changelog_min_free_cat_entries=3"; do
13814                 local MDT0=$(facet_svc $SINGLEMDS)
13815                 local var="${param%=*}"
13816                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13817
13818                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13819                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13820                         error "unable to set mdd.*.$param"
13821         done
13822
13823         # simulate changelog catalog almost full
13824         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13825         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13826
13827         for i in $(seq $MDSCOUNT); do
13828                 cl_users=(${CL_USERS[mds$i]})
13829                 cl_user1[mds$i]="${cl_users[0]}"
13830                 cl_user2[mds$i]="${cl_users[1]}"
13831
13832                 [ -n "${cl_user1[mds$i]}" ] ||
13833                         error "mds$i: no user registered"
13834                 [ -n "${cl_user2[mds$i]}" ] ||
13835                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13836
13837                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13838                 [ -n "$user_rec1" ] ||
13839                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13840                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13841                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13842                 [ -n "$user_rec2" ] ||
13843                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13844                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13845                      "$user_rec1 + 2 == $user_rec2"
13846                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13847                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13848                               "$user_rec1 + 2, but is $user_rec2"
13849                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13850                 [ -n "$user_rec2" ] ||
13851                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13852                 [ $user_rec1 == $user_rec2 ] ||
13853                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13854                               "$user_rec1, but is $user_rec2"
13855         done
13856
13857         # ensure we are past the previous changelog_min_gc_interval set above
13858         sleep 2
13859
13860         # generate one more changelog to trigger fail_loc
13861         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13862                 error "create $DIR/$tdir/${tfile}bis failed"
13863
13864         # ensure gc thread is done
13865         for i in $(mdts_nodes); do
13866                 wait_update $i \
13867                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13868                         error "$i: GC-thread not done"
13869         done
13870
13871         local first_rec
13872         for i in $(seq $MDSCOUNT); do
13873                 # check cl_user1 still registered
13874                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13875                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13876                 # check cl_user2 unregistered
13877                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13878                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13879
13880                 # check changelogs are present and starting at $user_rec1 + 1
13881                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13882                 [ -n "$user_rec1" ] ||
13883                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13884                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13885                             awk '{ print $1; exit; }')
13886
13887                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13888                 [ $((user_rec1 + 1)) == $first_rec ] ||
13889                         error "mds$i: first index should be $user_rec1 + 1, " \
13890                               "but is $first_rec"
13891         done
13892 }
13893 run_test 160g "changelog garbage collect (old users)"
13894
13895 test_160h() {
13896         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13897         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13898                 skip "Need MDS version at least 2.10.56"
13899
13900         local mdts=$(comma_list $(mdts_nodes))
13901
13902         # Create a user
13903         changelog_register || error "first changelog_register failed"
13904         changelog_register || error "second changelog_register failed"
13905         local cl_users
13906         declare -A cl_user1
13907         declare -A cl_user2
13908         local user_rec1
13909         local user_rec2
13910         local i
13911
13912         # generate some changelog records to accumulate on each MDT
13913         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13914         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13915                 error "create $DIR/$tdir/$tfile failed"
13916
13917         # check changelogs have been generated
13918         local nbcl=$(changelog_dump | wc -l)
13919         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13920
13921         for param in "changelog_max_idle_time=10" \
13922                      "changelog_gc=1" \
13923                      "changelog_min_gc_interval=2"; do
13924                 local MDT0=$(facet_svc $SINGLEMDS)
13925                 local var="${param%=*}"
13926                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13927
13928                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13929                 do_nodes $mdts $LCTL set_param mdd.*.$param
13930         done
13931
13932         # force cl_user2 to be idle (1st part)
13933         sleep 9
13934
13935         for i in $(seq $MDSCOUNT); do
13936                 cl_users=(${CL_USERS[mds$i]})
13937                 cl_user1[mds$i]="${cl_users[0]}"
13938                 cl_user2[mds$i]="${cl_users[1]}"
13939
13940                 [ -n "${cl_user1[mds$i]}" ] ||
13941                         error "mds$i: no user registered"
13942                 [ -n "${cl_user2[mds$i]}" ] ||
13943                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13944
13945                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13946                 [ -n "$user_rec1" ] ||
13947                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13948                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13949                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13950                 [ -n "$user_rec2" ] ||
13951                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13952                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13953                      "$user_rec1 + 2 == $user_rec2"
13954                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13955                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13956                               "$user_rec1 + 2, but is $user_rec2"
13957                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13958                 [ -n "$user_rec2" ] ||
13959                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13960                 [ $user_rec1 == $user_rec2 ] ||
13961                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13962                               "$user_rec1, but is $user_rec2"
13963         done
13964
13965         # force cl_user2 to be idle (2nd part) and to reach
13966         # changelog_max_idle_time
13967         sleep 2
13968
13969         # force each GC-thread start and block then
13970         # one per MDT/MDD, set fail_val accordingly
13971         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
13972         do_nodes $mdts $LCTL set_param fail_loc=0x1316
13973
13974         # generate more changelogs to trigger fail_loc
13975         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13976                 error "create $DIR/$tdir/${tfile}bis failed"
13977
13978         # stop MDT to stop GC-thread, should be done in back-ground as it will
13979         # block waiting for the thread to be released and exit
13980         declare -A stop_pids
13981         for i in $(seq $MDSCOUNT); do
13982                 stop mds$i &
13983                 stop_pids[mds$i]=$!
13984         done
13985
13986         for i in $(mdts_nodes); do
13987                 local facet
13988                 local nb=0
13989                 local facets=$(facets_up_on_host $i)
13990
13991                 for facet in ${facets//,/ }; do
13992                         if [[ $facet == mds* ]]; then
13993                                 nb=$((nb + 1))
13994                         fi
13995                 done
13996                 # ensure each MDS's gc threads are still present and all in "R"
13997                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
13998                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
13999                         error "$i: expected $nb GC-thread"
14000                 wait_update $i \
14001                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14002                         "R" 20 ||
14003                         error "$i: GC-thread not found in R-state"
14004                 # check umounts of each MDT on MDS have reached kthread_stop()
14005                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14006                         error "$i: expected $nb umount"
14007                 wait_update $i \
14008                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14009                         error "$i: umount not found in D-state"
14010         done
14011
14012         # release all GC-threads
14013         do_nodes $mdts $LCTL set_param fail_loc=0
14014
14015         # wait for MDT stop to complete
14016         for i in $(seq $MDSCOUNT); do
14017                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14018         done
14019
14020         # XXX
14021         # may try to check if any orphan changelog records are present
14022         # via ldiskfs/zfs and llog_reader...
14023
14024         # re-start/mount MDTs
14025         for i in $(seq $MDSCOUNT); do
14026                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14027                         error "Fail to start mds$i"
14028         done
14029
14030         local first_rec
14031         for i in $(seq $MDSCOUNT); do
14032                 # check cl_user1 still registered
14033                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14034                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14035                 # check cl_user2 unregistered
14036                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14037                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14038
14039                 # check changelogs are present and starting at $user_rec1 + 1
14040                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14041                 [ -n "$user_rec1" ] ||
14042                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14043                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14044                             awk '{ print $1; exit; }')
14045
14046                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14047                 [ $((user_rec1 + 1)) == $first_rec ] ||
14048                         error "mds$i: first index should be $user_rec1 + 1, " \
14049                               "but is $first_rec"
14050         done
14051 }
14052 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14053               "during mount"
14054
14055 test_160i() {
14056
14057         local mdts=$(comma_list $(mdts_nodes))
14058
14059         changelog_register || error "first changelog_register failed"
14060
14061         # generate some changelog records to accumulate on each MDT
14062         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14063         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14064                 error "create $DIR/$tdir/$tfile failed"
14065
14066         # check changelogs have been generated
14067         local nbcl=$(changelog_dump | wc -l)
14068         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14069
14070         # simulate race between register and unregister
14071         # XXX as fail_loc is set per-MDS, with DNE configs the race
14072         # simulation will only occur for one MDT per MDS and for the
14073         # others the normal race scenario will take place
14074         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14075         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14076         do_nodes $mdts $LCTL set_param fail_val=1
14077
14078         # unregister 1st user
14079         changelog_deregister &
14080         local pid1=$!
14081         # wait some time for deregister work to reach race rdv
14082         sleep 2
14083         # register 2nd user
14084         changelog_register || error "2nd user register failed"
14085
14086         wait $pid1 || error "1st user deregister failed"
14087
14088         local i
14089         local last_rec
14090         declare -A LAST_REC
14091         for i in $(seq $MDSCOUNT); do
14092                 if changelog_users mds$i | grep "^cl"; then
14093                         # make sure new records are added with one user present
14094                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14095                                           awk '/^current.index:/ { print $NF }')
14096                 else
14097                         error "mds$i has no user registered"
14098                 fi
14099         done
14100
14101         # generate more changelog records to accumulate on each MDT
14102         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14103                 error "create $DIR/$tdir/${tfile}bis failed"
14104
14105         for i in $(seq $MDSCOUNT); do
14106                 last_rec=$(changelog_users $SINGLEMDS |
14107                            awk '/^current.index:/ { print $NF }')
14108                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14109                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14110                         error "changelogs are off on mds$i"
14111         done
14112 }
14113 run_test 160i "changelog user register/unregister race"
14114
14115 test_160j() {
14116         remote_mds_nodsh && skip "remote MDS with nodsh"
14117         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14118                 skip "Need MDS version at least 2.12.56"
14119
14120         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14121
14122         changelog_register || error "first changelog_register failed"
14123
14124         # generate some changelog
14125         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14126         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14127                 error "create $DIR/$tdir/${tfile}bis failed"
14128
14129         # open the changelog device
14130         exec 3>/dev/changelog-$FSNAME-MDT0000
14131         exec 4</dev/changelog-$FSNAME-MDT0000
14132
14133         # umount the first lustre mount
14134         umount $MOUNT
14135
14136         # read changelog
14137         cat <&4 >/dev/null || error "read changelog failed"
14138
14139         # clear changelog
14140         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14141         changelog_users $SINGLEMDS | grep -q $cl_user ||
14142                 error "User $cl_user not found in changelog_users"
14143
14144         printf 'clear:'$cl_user':0' >&3
14145
14146         # close
14147         exec 3>&-
14148         exec 4<&-
14149
14150         # cleanup
14151         changelog_deregister || error "changelog_deregister failed"
14152
14153         umount $MOUNT2
14154         mount_client $MOUNT || error "mount_client on $MOUNT failed"
14155 }
14156 run_test 160j "client can be umounted  while its chanangelog is being used"
14157
14158 test_160k() {
14159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14160         remote_mds_nodsh && skip "remote MDS with nodsh"
14161
14162         mkdir -p $DIR/$tdir/1/1
14163
14164         changelog_register || error "changelog_register failed"
14165         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14166
14167         changelog_users $SINGLEMDS | grep -q $cl_user ||
14168                 error "User '$cl_user' not found in changelog_users"
14169 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14170         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14171         rmdir $DIR/$tdir/1/1 & sleep 1
14172         mkdir $DIR/$tdir/2
14173         touch $DIR/$tdir/2/2
14174         rm -rf $DIR/$tdir/2
14175
14176         wait
14177         sleep 4
14178
14179         changelog_dump | grep rmdir || error "rmdir not recorded"
14180
14181         rm -rf $DIR/$tdir
14182         changelog_deregister
14183 }
14184 run_test 160k "Verify that changelog records are not lost"
14185
14186 test_161a() {
14187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14188
14189         test_mkdir -c1 $DIR/$tdir
14190         cp /etc/hosts $DIR/$tdir/$tfile
14191         test_mkdir -c1 $DIR/$tdir/foo1
14192         test_mkdir -c1 $DIR/$tdir/foo2
14193         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14194         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14195         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14196         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14197         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14198         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14199                 $LFS fid2path $DIR $FID
14200                 error "bad link ea"
14201         fi
14202         # middle
14203         rm $DIR/$tdir/foo2/zachary
14204         # last
14205         rm $DIR/$tdir/foo2/thor
14206         # first
14207         rm $DIR/$tdir/$tfile
14208         # rename
14209         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
14210         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
14211                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
14212         rm $DIR/$tdir/foo2/maggie
14213
14214         # overflow the EA
14215         local longname=$tfile.avg_len_is_thirty_two_
14216         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
14217                 error_noexit 'failed to unlink many hardlinks'" EXIT
14218         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
14219                 error "failed to hardlink many files"
14220         links=$($LFS fid2path $DIR $FID | wc -l)
14221         echo -n "${links}/1000 links in link EA"
14222         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
14223 }
14224 run_test 161a "link ea sanity"
14225
14226 test_161b() {
14227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14228         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
14229
14230         local MDTIDX=1
14231         local remote_dir=$DIR/$tdir/remote_dir
14232
14233         mkdir -p $DIR/$tdir
14234         $LFS mkdir -i $MDTIDX $remote_dir ||
14235                 error "create remote directory failed"
14236
14237         cp /etc/hosts $remote_dir/$tfile
14238         mkdir -p $remote_dir/foo1
14239         mkdir -p $remote_dir/foo2
14240         ln $remote_dir/$tfile $remote_dir/foo1/sofia
14241         ln $remote_dir/$tfile $remote_dir/foo2/zachary
14242         ln $remote_dir/$tfile $remote_dir/foo1/luna
14243         ln $remote_dir/$tfile $remote_dir/foo2/thor
14244
14245         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
14246                      tr -d ']')
14247         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14248                 $LFS fid2path $DIR $FID
14249                 error "bad link ea"
14250         fi
14251         # middle
14252         rm $remote_dir/foo2/zachary
14253         # last
14254         rm $remote_dir/foo2/thor
14255         # first
14256         rm $remote_dir/$tfile
14257         # rename
14258         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
14259         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
14260         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
14261                 $LFS fid2path $DIR $FID
14262                 error "bad link rename"
14263         fi
14264         rm $remote_dir/foo2/maggie
14265
14266         # overflow the EA
14267         local longname=filename_avg_len_is_thirty_two_
14268         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
14269                 error "failed to hardlink many files"
14270         links=$($LFS fid2path $DIR $FID | wc -l)
14271         echo -n "${links}/1000 links in link EA"
14272         [[ ${links} -gt 60 ]] ||
14273                 error "expected at least 60 links in link EA"
14274         unlinkmany $remote_dir/foo2/$longname 1000 ||
14275         error "failed to unlink many hardlinks"
14276 }
14277 run_test 161b "link ea sanity under remote directory"
14278
14279 test_161c() {
14280         remote_mds_nodsh && skip "remote MDS with nodsh"
14281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14282         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
14283                 skip "Need MDS version at least 2.1.5"
14284
14285         # define CLF_RENAME_LAST 0x0001
14286         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
14287         changelog_register || error "changelog_register failed"
14288
14289         rm -rf $DIR/$tdir
14290         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
14291         touch $DIR/$tdir/foo_161c
14292         touch $DIR/$tdir/bar_161c
14293         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14294         changelog_dump | grep RENME | tail -n 5
14295         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14296         changelog_clear 0 || error "changelog_clear failed"
14297         if [ x$flags != "x0x1" ]; then
14298                 error "flag $flags is not 0x1"
14299         fi
14300
14301         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
14302         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
14303         touch $DIR/$tdir/foo_161c
14304         touch $DIR/$tdir/bar_161c
14305         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14306         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14307         changelog_dump | grep RENME | tail -n 5
14308         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14309         changelog_clear 0 || error "changelog_clear failed"
14310         if [ x$flags != "x0x0" ]; then
14311                 error "flag $flags is not 0x0"
14312         fi
14313         echo "rename overwrite a target having nlink > 1," \
14314                 "changelog record has flags of $flags"
14315
14316         # rename doesn't overwrite a target (changelog flag 0x0)
14317         touch $DIR/$tdir/foo_161c
14318         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
14319         changelog_dump | grep RENME | tail -n 5
14320         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
14321         changelog_clear 0 || error "changelog_clear failed"
14322         if [ x$flags != "x0x0" ]; then
14323                 error "flag $flags is not 0x0"
14324         fi
14325         echo "rename doesn't overwrite a target," \
14326                 "changelog record has flags of $flags"
14327
14328         # define CLF_UNLINK_LAST 0x0001
14329         # unlink a file having nlink = 1 (changelog flag 0x1)
14330         rm -f $DIR/$tdir/foo2_161c
14331         changelog_dump | grep UNLNK | tail -n 5
14332         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14333         changelog_clear 0 || error "changelog_clear failed"
14334         if [ x$flags != "x0x1" ]; then
14335                 error "flag $flags is not 0x1"
14336         fi
14337         echo "unlink a file having nlink = 1," \
14338                 "changelog record has flags of $flags"
14339
14340         # unlink a file having nlink > 1 (changelog flag 0x0)
14341         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14342         rm -f $DIR/$tdir/foobar_161c
14343         changelog_dump | grep UNLNK | tail -n 5
14344         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14345         changelog_clear 0 || error "changelog_clear failed"
14346         if [ x$flags != "x0x0" ]; then
14347                 error "flag $flags is not 0x0"
14348         fi
14349         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
14350 }
14351 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
14352
14353 test_161d() {
14354         remote_mds_nodsh && skip "remote MDS with nodsh"
14355         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
14356
14357         local pid
14358         local fid
14359
14360         changelog_register || error "changelog_register failed"
14361
14362         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
14363         # interfer with $MOUNT/.lustre/fid/ access
14364         mkdir $DIR/$tdir
14365         [[ $? -eq 0 ]] || error "mkdir failed"
14366
14367         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
14368         $LCTL set_param fail_loc=0x8000140c
14369         # 5s pause
14370         $LCTL set_param fail_val=5
14371
14372         # create file
14373         echo foofoo > $DIR/$tdir/$tfile &
14374         pid=$!
14375
14376         # wait for create to be delayed
14377         sleep 2
14378
14379         ps -p $pid
14380         [[ $? -eq 0 ]] || error "create should be blocked"
14381
14382         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
14383         stack_trap "rm -f $tempfile"
14384         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
14385         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
14386         # some delay may occur during ChangeLog publishing and file read just
14387         # above, that could allow file write to happen finally
14388         [[ -s $tempfile ]] && echo "file should be empty"
14389
14390         $LCTL set_param fail_loc=0
14391
14392         wait $pid
14393         [[ $? -eq 0 ]] || error "create failed"
14394 }
14395 run_test 161d "create with concurrent .lustre/fid access"
14396
14397 check_path() {
14398         local expected="$1"
14399         shift
14400         local fid="$2"
14401
14402         local path
14403         path=$($LFS fid2path "$@")
14404         local rc=$?
14405
14406         if [ $rc -ne 0 ]; then
14407                 error "path looked up of '$expected' failed: rc=$rc"
14408         elif [ "$path" != "$expected" ]; then
14409                 error "path looked up '$path' instead of '$expected'"
14410         else
14411                 echo "FID '$fid' resolves to path '$path' as expected"
14412         fi
14413 }
14414
14415 test_162a() { # was test_162
14416         test_mkdir -p -c1 $DIR/$tdir/d2
14417         touch $DIR/$tdir/d2/$tfile
14418         touch $DIR/$tdir/d2/x1
14419         touch $DIR/$tdir/d2/x2
14420         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
14421         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
14422         # regular file
14423         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
14424         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
14425
14426         # softlink
14427         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
14428         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
14429         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
14430
14431         # softlink to wrong file
14432         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
14433         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
14434         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
14435
14436         # hardlink
14437         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
14438         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
14439         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
14440         # fid2path dir/fsname should both work
14441         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
14442         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
14443
14444         # hardlink count: check that there are 2 links
14445         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
14446         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
14447
14448         # hardlink indexing: remove the first link
14449         rm $DIR/$tdir/d2/p/q/r/hlink
14450         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
14451 }
14452 run_test 162a "path lookup sanity"
14453
14454 test_162b() {
14455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14456         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14457
14458         mkdir $DIR/$tdir
14459         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
14460                                 error "create striped dir failed"
14461
14462         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
14463                                         tail -n 1 | awk '{print $2}')
14464         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
14465
14466         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
14467         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
14468
14469         # regular file
14470         for ((i=0;i<5;i++)); do
14471                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
14472                         error "get fid for f$i failed"
14473                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
14474
14475                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
14476                         error "get fid for d$i failed"
14477                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
14478         done
14479
14480         return 0
14481 }
14482 run_test 162b "striped directory path lookup sanity"
14483
14484 # LU-4239: Verify fid2path works with paths 100 or more directories deep
14485 test_162c() {
14486         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
14487                 skip "Need MDS version at least 2.7.51"
14488
14489         local lpath=$tdir.local
14490         local rpath=$tdir.remote
14491
14492         test_mkdir $DIR/$lpath
14493         test_mkdir $DIR/$rpath
14494
14495         for ((i = 0; i <= 101; i++)); do
14496                 lpath="$lpath/$i"
14497                 mkdir $DIR/$lpath
14498                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
14499                         error "get fid for local directory $DIR/$lpath failed"
14500                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
14501
14502                 rpath="$rpath/$i"
14503                 test_mkdir $DIR/$rpath
14504                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
14505                         error "get fid for remote directory $DIR/$rpath failed"
14506                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
14507         done
14508
14509         return 0
14510 }
14511 run_test 162c "fid2path works with paths 100 or more directories deep"
14512
14513 test_169() {
14514         # do directio so as not to populate the page cache
14515         log "creating a 10 Mb file"
14516         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14517         log "starting reads"
14518         dd if=$DIR/$tfile of=/dev/null bs=4096 &
14519         log "truncating the file"
14520         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14521         log "killing dd"
14522         kill %+ || true # reads might have finished
14523         echo "wait until dd is finished"
14524         wait
14525         log "removing the temporary file"
14526         rm -rf $DIR/$tfile || error "tmp file removal failed"
14527 }
14528 run_test 169 "parallel read and truncate should not deadlock"
14529
14530 test_170() {
14531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14532
14533         $LCTL clear     # bug 18514
14534         $LCTL debug_daemon start $TMP/${tfile}_log_good
14535         touch $DIR/$tfile
14536         $LCTL debug_daemon stop
14537         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
14538                 error "sed failed to read log_good"
14539
14540         $LCTL debug_daemon start $TMP/${tfile}_log_good
14541         rm -rf $DIR/$tfile
14542         $LCTL debug_daemon stop
14543
14544         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
14545                error "lctl df log_bad failed"
14546
14547         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14548         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14549
14550         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
14551         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
14552
14553         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
14554                 error "bad_line good_line1 good_line2 are empty"
14555
14556         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14557         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14558         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14559
14560         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14561         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14562         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14563
14564         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14565                 error "bad_line_new good_line_new are empty"
14566
14567         local expected_good=$((good_line1 + good_line2*2))
14568
14569         rm -f $TMP/${tfile}*
14570         # LU-231, short malformed line may not be counted into bad lines
14571         if [ $bad_line -ne $bad_line_new ] &&
14572                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14573                 error "expected $bad_line bad lines, but got $bad_line_new"
14574                 return 1
14575         fi
14576
14577         if [ $expected_good -ne $good_line_new ]; then
14578                 error "expected $expected_good good lines, but got $good_line_new"
14579                 return 2
14580         fi
14581         true
14582 }
14583 run_test 170 "test lctl df to handle corrupted log ====================="
14584
14585 test_171() { # bug20592
14586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14587
14588         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
14589         $LCTL set_param fail_loc=0x50e
14590         $LCTL set_param fail_val=3000
14591         multiop_bg_pause $DIR/$tfile O_s || true
14592         local MULTIPID=$!
14593         kill -USR1 $MULTIPID
14594         # cause log dump
14595         sleep 3
14596         wait $MULTIPID
14597         if dmesg | grep "recursive fault"; then
14598                 error "caught a recursive fault"
14599         fi
14600         $LCTL set_param fail_loc=0
14601         true
14602 }
14603 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
14604
14605 # it would be good to share it with obdfilter-survey/iokit-libecho code
14606 setup_obdecho_osc () {
14607         local rc=0
14608         local ost_nid=$1
14609         local obdfilter_name=$2
14610         echo "Creating new osc for $obdfilter_name on $ost_nid"
14611         # make sure we can find loopback nid
14612         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
14613
14614         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
14615                            ${obdfilter_name}_osc_UUID || rc=2; }
14616         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
14617                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
14618         return $rc
14619 }
14620
14621 cleanup_obdecho_osc () {
14622         local obdfilter_name=$1
14623         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14624         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14625         return 0
14626 }
14627
14628 obdecho_test() {
14629         local OBD=$1
14630         local node=$2
14631         local pages=${3:-64}
14632         local rc=0
14633         local id
14634
14635         local count=10
14636         local obd_size=$(get_obd_size $node $OBD)
14637         local page_size=$(get_page_size $node)
14638         if [[ -n "$obd_size" ]]; then
14639                 local new_count=$((obd_size / (pages * page_size / 1024)))
14640                 [[ $new_count -ge $count ]] || count=$new_count
14641         fi
14642
14643         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14644         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14645                            rc=2; }
14646         if [ $rc -eq 0 ]; then
14647             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14648             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14649         fi
14650         echo "New object id is $id"
14651         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14652                            rc=4; }
14653         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14654                            "test_brw $count w v $pages $id" || rc=4; }
14655         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14656                            rc=4; }
14657         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14658                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14659         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14660                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14661         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14662         return $rc
14663 }
14664
14665 test_180a() {
14666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14667
14668         if ! module_loaded obdecho; then
14669                 load_module obdecho/obdecho &&
14670                         stack_trap "rmmod obdecho" EXIT ||
14671                         error "unable to load obdecho on client"
14672         fi
14673
14674         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14675         local host=$($LCTL get_param -n osc.$osc.import |
14676                      awk '/current_connection:/ { print $2 }' )
14677         local target=$($LCTL get_param -n osc.$osc.import |
14678                        awk '/target:/ { print $2 }' )
14679         target=${target%_UUID}
14680
14681         if [ -n "$target" ]; then
14682                 setup_obdecho_osc $host $target &&
14683                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14684                         { error "obdecho setup failed with $?"; return; }
14685
14686                 obdecho_test ${target}_osc client ||
14687                         error "obdecho_test failed on ${target}_osc"
14688         else
14689                 $LCTL get_param osc.$osc.import
14690                 error "there is no osc.$osc.import target"
14691         fi
14692 }
14693 run_test 180a "test obdecho on osc"
14694
14695 test_180b() {
14696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14697         remote_ost_nodsh && skip "remote OST with nodsh"
14698
14699         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14700                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14701                 error "failed to load module obdecho"
14702
14703         local target=$(do_facet ost1 $LCTL dl |
14704                        awk '/obdfilter/ { print $4; exit; }')
14705
14706         if [ -n "$target" ]; then
14707                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14708         else
14709                 do_facet ost1 $LCTL dl
14710                 error "there is no obdfilter target on ost1"
14711         fi
14712 }
14713 run_test 180b "test obdecho directly on obdfilter"
14714
14715 test_180c() { # LU-2598
14716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14717         remote_ost_nodsh && skip "remote OST with nodsh"
14718         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14719                 skip "Need MDS version at least 2.4.0"
14720
14721         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14722                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14723                 error "failed to load module obdecho"
14724
14725         local target=$(do_facet ost1 $LCTL dl |
14726                        awk '/obdfilter/ { print $4; exit; }')
14727
14728         if [ -n "$target" ]; then
14729                 local pages=16384 # 64MB bulk I/O RPC size
14730
14731                 obdecho_test "$target" ost1 "$pages" ||
14732                         error "obdecho_test with pages=$pages failed with $?"
14733         else
14734                 do_facet ost1 $LCTL dl
14735                 error "there is no obdfilter target on ost1"
14736         fi
14737 }
14738 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14739
14740 test_181() { # bug 22177
14741         test_mkdir $DIR/$tdir
14742         # create enough files to index the directory
14743         createmany -o $DIR/$tdir/foobar 4000
14744         # print attributes for debug purpose
14745         lsattr -d .
14746         # open dir
14747         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14748         MULTIPID=$!
14749         # remove the files & current working dir
14750         unlinkmany $DIR/$tdir/foobar 4000
14751         rmdir $DIR/$tdir
14752         kill -USR1 $MULTIPID
14753         wait $MULTIPID
14754         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14755         return 0
14756 }
14757 run_test 181 "Test open-unlinked dir ========================"
14758
14759 test_182() {
14760         local fcount=1000
14761         local tcount=10
14762
14763         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14764
14765         $LCTL set_param mdc.*.rpc_stats=clear
14766
14767         for (( i = 0; i < $tcount; i++ )) ; do
14768                 mkdir $DIR/$tdir/$i
14769         done
14770
14771         for (( i = 0; i < $tcount; i++ )) ; do
14772                 createmany -o $DIR/$tdir/$i/f- $fcount &
14773         done
14774         wait
14775
14776         for (( i = 0; i < $tcount; i++ )) ; do
14777                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14778         done
14779         wait
14780
14781         $LCTL get_param mdc.*.rpc_stats
14782
14783         rm -rf $DIR/$tdir
14784 }
14785 run_test 182 "Test parallel modify metadata operations ================"
14786
14787 test_183() { # LU-2275
14788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14789         remote_mds_nodsh && skip "remote MDS with nodsh"
14790         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14791                 skip "Need MDS version at least 2.3.56"
14792
14793         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14794         echo aaa > $DIR/$tdir/$tfile
14795
14796 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14797         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14798
14799         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14800         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14801
14802         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14803
14804         # Flush negative dentry cache
14805         touch $DIR/$tdir/$tfile
14806
14807         # We are not checking for any leaked references here, they'll
14808         # become evident next time we do cleanup with module unload.
14809         rm -rf $DIR/$tdir
14810 }
14811 run_test 183 "No crash or request leak in case of strange dispositions ========"
14812
14813 # test suite 184 is for LU-2016, LU-2017
14814 test_184a() {
14815         check_swap_layouts_support
14816
14817         dir0=$DIR/$tdir/$testnum
14818         test_mkdir -p -c1 $dir0
14819         ref1=/etc/passwd
14820         ref2=/etc/group
14821         file1=$dir0/f1
14822         file2=$dir0/f2
14823         $LFS setstripe -c1 $file1
14824         cp $ref1 $file1
14825         $LFS setstripe -c2 $file2
14826         cp $ref2 $file2
14827         gen1=$($LFS getstripe -g $file1)
14828         gen2=$($LFS getstripe -g $file2)
14829
14830         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14831         gen=$($LFS getstripe -g $file1)
14832         [[ $gen1 != $gen ]] ||
14833                 "Layout generation on $file1 does not change"
14834         gen=$($LFS getstripe -g $file2)
14835         [[ $gen2 != $gen ]] ||
14836                 "Layout generation on $file2 does not change"
14837
14838         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14839         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14840
14841         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14842 }
14843 run_test 184a "Basic layout swap"
14844
14845 test_184b() {
14846         check_swap_layouts_support
14847
14848         dir0=$DIR/$tdir/$testnum
14849         mkdir -p $dir0 || error "creating dir $dir0"
14850         file1=$dir0/f1
14851         file2=$dir0/f2
14852         file3=$dir0/f3
14853         dir1=$dir0/d1
14854         dir2=$dir0/d2
14855         mkdir $dir1 $dir2
14856         $LFS setstripe -c1 $file1
14857         $LFS setstripe -c2 $file2
14858         $LFS setstripe -c1 $file3
14859         chown $RUNAS_ID $file3
14860         gen1=$($LFS getstripe -g $file1)
14861         gen2=$($LFS getstripe -g $file2)
14862
14863         $LFS swap_layouts $dir1 $dir2 &&
14864                 error "swap of directories layouts should fail"
14865         $LFS swap_layouts $dir1 $file1 &&
14866                 error "swap of directory and file layouts should fail"
14867         $RUNAS $LFS swap_layouts $file1 $file2 &&
14868                 error "swap of file we cannot write should fail"
14869         $LFS swap_layouts $file1 $file3 &&
14870                 error "swap of file with different owner should fail"
14871         /bin/true # to clear error code
14872 }
14873 run_test 184b "Forbidden layout swap (will generate errors)"
14874
14875 test_184c() {
14876         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14877         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14878         check_swap_layouts_support
14879
14880         local dir0=$DIR/$tdir/$testnum
14881         mkdir -p $dir0 || error "creating dir $dir0"
14882
14883         local ref1=$dir0/ref1
14884         local ref2=$dir0/ref2
14885         local file1=$dir0/file1
14886         local file2=$dir0/file2
14887         # create a file large enough for the concurrent test
14888         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14889         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14890         echo "ref file size: ref1($(stat -c %s $ref1))," \
14891              "ref2($(stat -c %s $ref2))"
14892
14893         cp $ref2 $file2
14894         dd if=$ref1 of=$file1 bs=16k &
14895         local DD_PID=$!
14896
14897         # Make sure dd starts to copy file
14898         while [ ! -f $file1 ]; do sleep 0.1; done
14899
14900         $LFS swap_layouts $file1 $file2
14901         local rc=$?
14902         wait $DD_PID
14903         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14904         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14905
14906         # how many bytes copied before swapping layout
14907         local copied=$(stat -c %s $file2)
14908         local remaining=$(stat -c %s $ref1)
14909         remaining=$((remaining - copied))
14910         echo "Copied $copied bytes before swapping layout..."
14911
14912         cmp -n $copied $file1 $ref2 | grep differ &&
14913                 error "Content mismatch [0, $copied) of ref2 and file1"
14914         cmp -n $copied $file2 $ref1 ||
14915                 error "Content mismatch [0, $copied) of ref1 and file2"
14916         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14917                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14918
14919         # clean up
14920         rm -f $ref1 $ref2 $file1 $file2
14921 }
14922 run_test 184c "Concurrent write and layout swap"
14923
14924 test_184d() {
14925         check_swap_layouts_support
14926         [ -z "$(which getfattr 2>/dev/null)" ] &&
14927                 skip_env "no getfattr command"
14928
14929         local file1=$DIR/$tdir/$tfile-1
14930         local file2=$DIR/$tdir/$tfile-2
14931         local file3=$DIR/$tdir/$tfile-3
14932         local lovea1
14933         local lovea2
14934
14935         mkdir -p $DIR/$tdir
14936         touch $file1 || error "create $file1 failed"
14937         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14938                 error "create $file2 failed"
14939         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14940                 error "create $file3 failed"
14941         lovea1=$(get_layout_param $file1)
14942
14943         $LFS swap_layouts $file2 $file3 ||
14944                 error "swap $file2 $file3 layouts failed"
14945         $LFS swap_layouts $file1 $file2 ||
14946                 error "swap $file1 $file2 layouts failed"
14947
14948         lovea2=$(get_layout_param $file2)
14949         echo "$lovea1"
14950         echo "$lovea2"
14951         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14952
14953         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14954         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14955 }
14956 run_test 184d "allow stripeless layouts swap"
14957
14958 test_184e() {
14959         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14960                 skip "Need MDS version at least 2.6.94"
14961         check_swap_layouts_support
14962         [ -z "$(which getfattr 2>/dev/null)" ] &&
14963                 skip_env "no getfattr command"
14964
14965         local file1=$DIR/$tdir/$tfile-1
14966         local file2=$DIR/$tdir/$tfile-2
14967         local file3=$DIR/$tdir/$tfile-3
14968         local lovea
14969
14970         mkdir -p $DIR/$tdir
14971         touch $file1 || error "create $file1 failed"
14972         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14973                 error "create $file2 failed"
14974         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14975                 error "create $file3 failed"
14976
14977         $LFS swap_layouts $file1 $file2 ||
14978                 error "swap $file1 $file2 layouts failed"
14979
14980         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14981         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
14982
14983         echo 123 > $file1 || error "Should be able to write into $file1"
14984
14985         $LFS swap_layouts $file1 $file3 ||
14986                 error "swap $file1 $file3 layouts failed"
14987
14988         echo 123 > $file1 || error "Should be able to write into $file1"
14989
14990         rm -rf $file1 $file2 $file3
14991 }
14992 run_test 184e "Recreate layout after stripeless layout swaps"
14993
14994 test_184f() {
14995         # Create a file with name longer than sizeof(struct stat) ==
14996         # 144 to see if we can get chars from the file name to appear
14997         # in the returned striping. Note that 'f' == 0x66.
14998         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
14999
15000         mkdir -p $DIR/$tdir
15001         mcreate $DIR/$tdir/$file
15002         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
15003                 error "IOC_MDC_GETFILEINFO returned garbage striping"
15004         fi
15005 }
15006 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
15007
15008 test_185() { # LU-2441
15009         # LU-3553 - no volatile file support in old servers
15010         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
15011                 skip "Need MDS version at least 2.3.60"
15012
15013         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15014         touch $DIR/$tdir/spoo
15015         local mtime1=$(stat -c "%Y" $DIR/$tdir)
15016         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
15017                 error "cannot create/write a volatile file"
15018         [ "$FILESET" == "" ] &&
15019         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
15020                 error "FID is still valid after close"
15021
15022         multiop_bg_pause $DIR/$tdir vVw4096_c
15023         local multi_pid=$!
15024
15025         local OLD_IFS=$IFS
15026         IFS=":"
15027         local fidv=($fid)
15028         IFS=$OLD_IFS
15029         # assume that the next FID for this client is sequential, since stdout
15030         # is unfortunately eaten by multiop_bg_pause
15031         local n=$((${fidv[1]} + 1))
15032         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
15033         if [ "$FILESET" == "" ]; then
15034                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
15035                         error "FID is missing before close"
15036         fi
15037         kill -USR1 $multi_pid
15038         # 1 second delay, so if mtime change we will see it
15039         sleep 1
15040         local mtime2=$(stat -c "%Y" $DIR/$tdir)
15041         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
15042 }
15043 run_test 185 "Volatile file support"
15044
15045 function create_check_volatile() {
15046         local idx=$1
15047         local tgt
15048
15049         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
15050         local PID=$!
15051         sleep 1
15052         local FID=$(cat /tmp/${tfile}.fid)
15053         [ "$FID" == "" ] && error "can't get FID for volatile"
15054         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
15055         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
15056         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
15057         kill -USR1 $PID
15058         wait
15059         sleep 1
15060         cancel_lru_locks mdc # flush opencache
15061         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
15062         return 0
15063 }
15064
15065 test_185a(){
15066         # LU-12516 - volatile creation via .lustre
15067         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
15068                 skip "Need MDS version at least 2.3.55"
15069
15070         create_check_volatile 0
15071         [ $MDSCOUNT -lt 2 ] && return 0
15072
15073         # DNE case
15074         create_check_volatile 1
15075
15076         return 0
15077 }
15078 run_test 185a "Volatile file creation in .lustre/fid/"
15079
15080 test_187a() {
15081         remote_mds_nodsh && skip "remote MDS with nodsh"
15082         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15083                 skip "Need MDS version at least 2.3.0"
15084
15085         local dir0=$DIR/$tdir/$testnum
15086         mkdir -p $dir0 || error "creating dir $dir0"
15087
15088         local file=$dir0/file1
15089         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
15090         local dv1=$($LFS data_version $file)
15091         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
15092         local dv2=$($LFS data_version $file)
15093         [[ $dv1 != $dv2 ]] ||
15094                 error "data version did not change on write $dv1 == $dv2"
15095
15096         # clean up
15097         rm -f $file1
15098 }
15099 run_test 187a "Test data version change"
15100
15101 test_187b() {
15102         remote_mds_nodsh && skip "remote MDS with nodsh"
15103         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15104                 skip "Need MDS version at least 2.3.0"
15105
15106         local dir0=$DIR/$tdir/$testnum
15107         mkdir -p $dir0 || error "creating dir $dir0"
15108
15109         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
15110         [[ ${DV[0]} != ${DV[1]} ]] ||
15111                 error "data version did not change on write"\
15112                       " ${DV[0]} == ${DV[1]}"
15113
15114         # clean up
15115         rm -f $file1
15116 }
15117 run_test 187b "Test data version change on volatile file"
15118
15119 test_200() {
15120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15121         remote_mgs_nodsh && skip "remote MGS with nodsh"
15122         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15123
15124         local POOL=${POOL:-cea1}
15125         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
15126         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
15127         # Pool OST targets
15128         local first_ost=0
15129         local last_ost=$(($OSTCOUNT - 1))
15130         local ost_step=2
15131         local ost_list=$(seq $first_ost $ost_step $last_ost)
15132         local ost_range="$first_ost $last_ost $ost_step"
15133         local test_path=$POOL_ROOT/$POOL_DIR_NAME
15134         local file_dir=$POOL_ROOT/file_tst
15135         local subdir=$test_path/subdir
15136         local rc=0
15137
15138         while : ; do
15139                 # former test_200a test_200b
15140                 pool_add $POOL                          || { rc=$? ; break; }
15141                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
15142                 # former test_200c test_200d
15143                 mkdir -p $test_path
15144                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
15145                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
15146                 mkdir -p $subdir
15147                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
15148                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
15149                                                         || { rc=$? ; break; }
15150                 # former test_200e test_200f
15151                 local files=$((OSTCOUNT*3))
15152                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
15153                                                         || { rc=$? ; break; }
15154                 pool_create_files $POOL $file_dir $files "$ost_list" \
15155                                                         || { rc=$? ; break; }
15156                 # former test_200g test_200h
15157                 pool_lfs_df $POOL                       || { rc=$? ; break; }
15158                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
15159
15160                 # former test_201a test_201b test_201c
15161                 pool_remove_first_target $POOL          || { rc=$? ; break; }
15162
15163                 local f=$test_path/$tfile
15164                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
15165                 pool_remove $POOL $f                    || { rc=$? ; break; }
15166                 break
15167         done
15168
15169         destroy_test_pools
15170
15171         return $rc
15172 }
15173 run_test 200 "OST pools"
15174
15175 # usage: default_attr <count | size | offset>
15176 default_attr() {
15177         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
15178 }
15179
15180 # usage: check_default_stripe_attr
15181 check_default_stripe_attr() {
15182         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
15183         case $1 in
15184         --stripe-count|-c)
15185                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
15186         --stripe-size|-S)
15187                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
15188         --stripe-index|-i)
15189                 EXPECTED=-1;;
15190         *)
15191                 error "unknown getstripe attr '$1'"
15192         esac
15193
15194         [ $ACTUAL == $EXPECTED ] ||
15195                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
15196 }
15197
15198 test_204a() {
15199         test_mkdir $DIR/$tdir
15200         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
15201
15202         check_default_stripe_attr --stripe-count
15203         check_default_stripe_attr --stripe-size
15204         check_default_stripe_attr --stripe-index
15205 }
15206 run_test 204a "Print default stripe attributes"
15207
15208 test_204b() {
15209         test_mkdir $DIR/$tdir
15210         $LFS setstripe --stripe-count 1 $DIR/$tdir
15211
15212         check_default_stripe_attr --stripe-size
15213         check_default_stripe_attr --stripe-index
15214 }
15215 run_test 204b "Print default stripe size and offset"
15216
15217 test_204c() {
15218         test_mkdir $DIR/$tdir
15219         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15220
15221         check_default_stripe_attr --stripe-count
15222         check_default_stripe_attr --stripe-index
15223 }
15224 run_test 204c "Print default stripe count and offset"
15225
15226 test_204d() {
15227         test_mkdir $DIR/$tdir
15228         $LFS setstripe --stripe-index 0 $DIR/$tdir
15229
15230         check_default_stripe_attr --stripe-count
15231         check_default_stripe_attr --stripe-size
15232 }
15233 run_test 204d "Print default stripe count and size"
15234
15235 test_204e() {
15236         test_mkdir $DIR/$tdir
15237         $LFS setstripe -d $DIR/$tdir
15238
15239         check_default_stripe_attr --stripe-count --raw
15240         check_default_stripe_attr --stripe-size --raw
15241         check_default_stripe_attr --stripe-index --raw
15242 }
15243 run_test 204e "Print raw stripe attributes"
15244
15245 test_204f() {
15246         test_mkdir $DIR/$tdir
15247         $LFS setstripe --stripe-count 1 $DIR/$tdir
15248
15249         check_default_stripe_attr --stripe-size --raw
15250         check_default_stripe_attr --stripe-index --raw
15251 }
15252 run_test 204f "Print raw stripe size and offset"
15253
15254 test_204g() {
15255         test_mkdir $DIR/$tdir
15256         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15257
15258         check_default_stripe_attr --stripe-count --raw
15259         check_default_stripe_attr --stripe-index --raw
15260 }
15261 run_test 204g "Print raw stripe count and offset"
15262
15263 test_204h() {
15264         test_mkdir $DIR/$tdir
15265         $LFS setstripe --stripe-index 0 $DIR/$tdir
15266
15267         check_default_stripe_attr --stripe-count --raw
15268         check_default_stripe_attr --stripe-size --raw
15269 }
15270 run_test 204h "Print raw stripe count and size"
15271
15272 # Figure out which job scheduler is being used, if any,
15273 # or use a fake one
15274 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
15275         JOBENV=SLURM_JOB_ID
15276 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
15277         JOBENV=LSB_JOBID
15278 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
15279         JOBENV=PBS_JOBID
15280 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
15281         JOBENV=LOADL_STEP_ID
15282 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
15283         JOBENV=JOB_ID
15284 else
15285         $LCTL list_param jobid_name > /dev/null 2>&1
15286         if [ $? -eq 0 ]; then
15287                 JOBENV=nodelocal
15288         else
15289                 JOBENV=FAKE_JOBID
15290         fi
15291 fi
15292 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
15293
15294 verify_jobstats() {
15295         local cmd=($1)
15296         shift
15297         local facets="$@"
15298
15299 # we don't really need to clear the stats for this test to work, since each
15300 # command has a unique jobid, but it makes debugging easier if needed.
15301 #       for facet in $facets; do
15302 #               local dev=$(convert_facet2label $facet)
15303 #               # clear old jobstats
15304 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
15305 #       done
15306
15307         # use a new JobID for each test, or we might see an old one
15308         [ "$JOBENV" = "FAKE_JOBID" ] &&
15309                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
15310
15311         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
15312
15313         [ "$JOBENV" = "nodelocal" ] && {
15314                 FAKE_JOBID=id.$testnum.%e.$RANDOM
15315                 $LCTL set_param jobid_name=$FAKE_JOBID
15316                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
15317         }
15318
15319         log "Test: ${cmd[*]}"
15320         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
15321
15322         if [ $JOBENV = "FAKE_JOBID" ]; then
15323                 FAKE_JOBID=$JOBVAL ${cmd[*]}
15324         else
15325                 ${cmd[*]}
15326         fi
15327
15328         # all files are created on OST0000
15329         for facet in $facets; do
15330                 local stats="*.$(convert_facet2label $facet).job_stats"
15331
15332                 # strip out libtool wrappers for in-tree executables
15333                 if [ $(do_facet $facet lctl get_param $stats |
15334                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
15335                         do_facet $facet lctl get_param $stats
15336                         error "No jobstats for $JOBVAL found on $facet::$stats"
15337                 fi
15338         done
15339 }
15340
15341 jobstats_set() {
15342         local new_jobenv=$1
15343
15344         set_persistent_param_and_check client "jobid_var" \
15345                 "$FSNAME.sys.jobid_var" $new_jobenv
15346 }
15347
15348 test_205() { # Job stats
15349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15350         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
15351                 skip "Need MDS version with at least 2.7.1"
15352         remote_mgs_nodsh && skip "remote MGS with nodsh"
15353         remote_mds_nodsh && skip "remote MDS with nodsh"
15354         remote_ost_nodsh && skip "remote OST with nodsh"
15355         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
15356                 skip "Server doesn't support jobstats"
15357         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
15358
15359         local old_jobenv=$($LCTL get_param -n jobid_var)
15360         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
15361
15362         if [[ $PERM_CMD == *"set_param -P"* ]]; then
15363                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
15364         else
15365                 stack_trap "do_facet mgs $PERM_CMD \
15366                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
15367         fi
15368         changelog_register
15369
15370         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
15371                                 mdt.*.job_cleanup_interval | head -n 1)
15372         local new_interval=5
15373         do_facet $SINGLEMDS \
15374                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
15375         stack_trap "do_facet $SINGLEMDS \
15376                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
15377         local start=$SECONDS
15378
15379         local cmd
15380         # mkdir
15381         cmd="mkdir $DIR/$tdir"
15382         verify_jobstats "$cmd" "$SINGLEMDS"
15383         # rmdir
15384         cmd="rmdir $DIR/$tdir"
15385         verify_jobstats "$cmd" "$SINGLEMDS"
15386         # mkdir on secondary MDT
15387         if [ $MDSCOUNT -gt 1 ]; then
15388                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
15389                 verify_jobstats "$cmd" "mds2"
15390         fi
15391         # mknod
15392         cmd="mknod $DIR/$tfile c 1 3"
15393         verify_jobstats "$cmd" "$SINGLEMDS"
15394         # unlink
15395         cmd="rm -f $DIR/$tfile"
15396         verify_jobstats "$cmd" "$SINGLEMDS"
15397         # create all files on OST0000 so verify_jobstats can find OST stats
15398         # open & close
15399         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
15400         verify_jobstats "$cmd" "$SINGLEMDS"
15401         # setattr
15402         cmd="touch $DIR/$tfile"
15403         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15404         # write
15405         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
15406         verify_jobstats "$cmd" "ost1"
15407         # read
15408         cancel_lru_locks osc
15409         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
15410         verify_jobstats "$cmd" "ost1"
15411         # truncate
15412         cmd="$TRUNCATE $DIR/$tfile 0"
15413         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15414         # rename
15415         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
15416         verify_jobstats "$cmd" "$SINGLEMDS"
15417         # jobstats expiry - sleep until old stats should be expired
15418         local left=$((new_interval + 5 - (SECONDS - start)))
15419         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
15420                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
15421                         "0" $left
15422         cmd="mkdir $DIR/$tdir.expire"
15423         verify_jobstats "$cmd" "$SINGLEMDS"
15424         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
15425             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
15426
15427         # Ensure that jobid are present in changelog (if supported by MDS)
15428         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
15429                 changelog_dump | tail -10
15430                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
15431                 [ $jobids -eq 9 ] ||
15432                         error "Wrong changelog jobid count $jobids != 9"
15433
15434                 # LU-5862
15435                 JOBENV="disable"
15436                 jobstats_set $JOBENV
15437                 touch $DIR/$tfile
15438                 changelog_dump | grep $tfile
15439                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
15440                 [ $jobids -eq 0 ] ||
15441                         error "Unexpected jobids when jobid_var=$JOBENV"
15442         fi
15443
15444         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
15445         JOBENV="JOBCOMPLEX"
15446         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
15447
15448         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
15449 }
15450 run_test 205 "Verify job stats"
15451
15452 # LU-1480, LU-1773 and LU-1657
15453 test_206() {
15454         mkdir -p $DIR/$tdir
15455         $LFS setstripe -c -1 $DIR/$tdir
15456 #define OBD_FAIL_LOV_INIT 0x1403
15457         $LCTL set_param fail_loc=0xa0001403
15458         $LCTL set_param fail_val=1
15459         touch $DIR/$tdir/$tfile || true
15460 }
15461 run_test 206 "fail lov_init_raid0() doesn't lbug"
15462
15463 test_207a() {
15464         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15465         local fsz=`stat -c %s $DIR/$tfile`
15466         cancel_lru_locks mdc
15467
15468         # do not return layout in getattr intent
15469 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
15470         $LCTL set_param fail_loc=0x170
15471         local sz=`stat -c %s $DIR/$tfile`
15472
15473         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
15474
15475         rm -rf $DIR/$tfile
15476 }
15477 run_test 207a "can refresh layout at glimpse"
15478
15479 test_207b() {
15480         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15481         local cksum=`md5sum $DIR/$tfile`
15482         local fsz=`stat -c %s $DIR/$tfile`
15483         cancel_lru_locks mdc
15484         cancel_lru_locks osc
15485
15486         # do not return layout in getattr intent
15487 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
15488         $LCTL set_param fail_loc=0x171
15489
15490         # it will refresh layout after the file is opened but before read issues
15491         echo checksum is "$cksum"
15492         echo "$cksum" |md5sum -c --quiet || error "file differs"
15493
15494         rm -rf $DIR/$tfile
15495 }
15496 run_test 207b "can refresh layout at open"
15497
15498 test_208() {
15499         # FIXME: in this test suite, only RD lease is used. This is okay
15500         # for now as only exclusive open is supported. After generic lease
15501         # is done, this test suite should be revised. - Jinshan
15502
15503         remote_mds_nodsh && skip "remote MDS with nodsh"
15504         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
15505                 skip "Need MDS version at least 2.4.52"
15506
15507         echo "==== test 1: verify get lease work"
15508         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
15509
15510         echo "==== test 2: verify lease can be broken by upcoming open"
15511         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15512         local PID=$!
15513         sleep 1
15514
15515         $MULTIOP $DIR/$tfile oO_RDONLY:c
15516         kill -USR1 $PID && wait $PID || error "break lease error"
15517
15518         echo "==== test 3: verify lease can't be granted if an open already exists"
15519         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
15520         local PID=$!
15521         sleep 1
15522
15523         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
15524         kill -USR1 $PID && wait $PID || error "open file error"
15525
15526         echo "==== test 4: lease can sustain over recovery"
15527         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
15528         PID=$!
15529         sleep 1
15530
15531         fail mds1
15532
15533         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
15534
15535         echo "==== test 5: lease broken can't be regained by replay"
15536         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15537         PID=$!
15538         sleep 1
15539
15540         # open file to break lease and then recovery
15541         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
15542         fail mds1
15543
15544         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
15545
15546         rm -f $DIR/$tfile
15547 }
15548 run_test 208 "Exclusive open"
15549
15550 test_209() {
15551         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15552                 skip_env "must have disp_stripe"
15553
15554         touch $DIR/$tfile
15555         sync; sleep 5; sync;
15556
15557         echo 3 > /proc/sys/vm/drop_caches
15558         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15559
15560         # open/close 500 times
15561         for i in $(seq 500); do
15562                 cat $DIR/$tfile
15563         done
15564
15565         echo 3 > /proc/sys/vm/drop_caches
15566         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15567
15568         echo "before: $req_before, after: $req_after"
15569         [ $((req_after - req_before)) -ge 300 ] &&
15570                 error "open/close requests are not freed"
15571         return 0
15572 }
15573 run_test 209 "read-only open/close requests should be freed promptly"
15574
15575 test_212() {
15576         size=`date +%s`
15577         size=$((size % 8192 + 1))
15578         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
15579         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
15580         rm -f $DIR/f212 $DIR/f212.xyz
15581 }
15582 run_test 212 "Sendfile test ============================================"
15583
15584 test_213() {
15585         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
15586         cancel_lru_locks osc
15587         lctl set_param fail_loc=0x8000040f
15588         # generate a read lock
15589         cat $DIR/$tfile > /dev/null
15590         # write to the file, it will try to cancel the above read lock.
15591         cat /etc/hosts >> $DIR/$tfile
15592 }
15593 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
15594
15595 test_214() { # for bug 20133
15596         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
15597         for (( i=0; i < 340; i++ )) ; do
15598                 touch $DIR/$tdir/d214c/a$i
15599         done
15600
15601         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
15602         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
15603         ls $DIR/d214c || error "ls $DIR/d214c failed"
15604         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
15605         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
15606 }
15607 run_test 214 "hash-indexed directory test - bug 20133"
15608
15609 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
15610 create_lnet_proc_files() {
15611         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
15612 }
15613
15614 # counterpart of create_lnet_proc_files
15615 remove_lnet_proc_files() {
15616         rm -f $TMP/lnet_$1.sys
15617 }
15618
15619 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15620 # 3rd arg as regexp for body
15621 check_lnet_proc_stats() {
15622         local l=$(cat "$TMP/lnet_$1" |wc -l)
15623         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
15624
15625         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
15626 }
15627
15628 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15629 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
15630 # optional and can be regexp for 2nd line (lnet.routes case)
15631 check_lnet_proc_entry() {
15632         local blp=2          # blp stands for 'position of 1st line of body'
15633         [ -z "$5" ] || blp=3 # lnet.routes case
15634
15635         local l=$(cat "$TMP/lnet_$1" |wc -l)
15636         # subtracting one from $blp because the body can be empty
15637         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
15638
15639         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
15640                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
15641
15642         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
15643                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
15644
15645         # bail out if any unexpected line happened
15646         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15647         [ "$?" != 0 ] || error "$2 misformatted"
15648 }
15649
15650 test_215() { # for bugs 18102, 21079, 21517
15651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15652
15653         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15654         local P='[1-9][0-9]*'           # positive numeric
15655         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15656         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15657         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15658         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15659
15660         local L1 # regexp for 1st line
15661         local L2 # regexp for 2nd line (optional)
15662         local BR # regexp for the rest (body)
15663
15664         # lnet.stats should look as 11 space-separated non-negative numerics
15665         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15666         create_lnet_proc_files "stats"
15667         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15668         remove_lnet_proc_files "stats"
15669
15670         # lnet.routes should look like this:
15671         # Routing disabled/enabled
15672         # net hops priority state router
15673         # where net is a string like tcp0, hops > 0, priority >= 0,
15674         # state is up/down,
15675         # router is a string like 192.168.1.1@tcp2
15676         L1="^Routing (disabled|enabled)$"
15677         L2="^net +hops +priority +state +router$"
15678         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15679         create_lnet_proc_files "routes"
15680         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15681         remove_lnet_proc_files "routes"
15682
15683         # lnet.routers should look like this:
15684         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15685         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15686         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15687         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15688         L1="^ref +rtr_ref +alive +router$"
15689         BR="^$P +$P +(up|down) +$NID$"
15690         create_lnet_proc_files "routers"
15691         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15692         remove_lnet_proc_files "routers"
15693
15694         # lnet.peers should look like this:
15695         # nid refs state last max rtr min tx min queue
15696         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15697         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15698         # numeric (0 or >0 or <0), queue >= 0.
15699         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15700         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15701         create_lnet_proc_files "peers"
15702         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15703         remove_lnet_proc_files "peers"
15704
15705         # lnet.buffers  should look like this:
15706         # pages count credits min
15707         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15708         L1="^pages +count +credits +min$"
15709         BR="^ +$N +$N +$I +$I$"
15710         create_lnet_proc_files "buffers"
15711         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15712         remove_lnet_proc_files "buffers"
15713
15714         # lnet.nis should look like this:
15715         # nid status alive refs peer rtr max tx min
15716         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15717         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15718         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15719         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15720         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15721         create_lnet_proc_files "nis"
15722         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15723         remove_lnet_proc_files "nis"
15724
15725         # can we successfully write to lnet.stats?
15726         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15727 }
15728 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15729
15730 test_216() { # bug 20317
15731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15732         remote_ost_nodsh && skip "remote OST with nodsh"
15733
15734         local node
15735         local facets=$(get_facets OST)
15736         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15737
15738         save_lustre_params client "osc.*.contention_seconds" > $p
15739         save_lustre_params $facets \
15740                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15741         save_lustre_params $facets \
15742                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15743         save_lustre_params $facets \
15744                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15745         clear_stats osc.*.osc_stats
15746
15747         # agressive lockless i/o settings
15748         do_nodes $(comma_list $(osts_nodes)) \
15749                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15750                         ldlm.namespaces.filter-*.contended_locks=0 \
15751                         ldlm.namespaces.filter-*.contention_seconds=60"
15752         lctl set_param -n osc.*.contention_seconds=60
15753
15754         $DIRECTIO write $DIR/$tfile 0 10 4096
15755         $CHECKSTAT -s 40960 $DIR/$tfile
15756
15757         # disable lockless i/o
15758         do_nodes $(comma_list $(osts_nodes)) \
15759                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15760                         ldlm.namespaces.filter-*.contended_locks=32 \
15761                         ldlm.namespaces.filter-*.contention_seconds=0"
15762         lctl set_param -n osc.*.contention_seconds=0
15763         clear_stats osc.*.osc_stats
15764
15765         dd if=/dev/zero of=$DIR/$tfile count=0
15766         $CHECKSTAT -s 0 $DIR/$tfile
15767
15768         restore_lustre_params <$p
15769         rm -f $p
15770         rm $DIR/$tfile
15771 }
15772 run_test 216 "check lockless direct write updates file size and kms correctly"
15773
15774 test_217() { # bug 22430
15775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15776
15777         local node
15778         local nid
15779
15780         for node in $(nodes_list); do
15781                 nid=$(host_nids_address $node $NETTYPE)
15782                 if [[ $nid = *-* ]] ; then
15783                         echo "lctl ping $(h2nettype $nid)"
15784                         lctl ping $(h2nettype $nid)
15785                 else
15786                         echo "skipping $node (no hyphen detected)"
15787                 fi
15788         done
15789 }
15790 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15791
15792 test_218() {
15793        # do directio so as not to populate the page cache
15794        log "creating a 10 Mb file"
15795        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15796        log "starting reads"
15797        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15798        log "truncating the file"
15799        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15800        log "killing dd"
15801        kill %+ || true # reads might have finished
15802        echo "wait until dd is finished"
15803        wait
15804        log "removing the temporary file"
15805        rm -rf $DIR/$tfile || error "tmp file removal failed"
15806 }
15807 run_test 218 "parallel read and truncate should not deadlock"
15808
15809 test_219() {
15810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15811
15812         # write one partial page
15813         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15814         # set no grant so vvp_io_commit_write will do sync write
15815         $LCTL set_param fail_loc=0x411
15816         # write a full page at the end of file
15817         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15818
15819         $LCTL set_param fail_loc=0
15820         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15821         $LCTL set_param fail_loc=0x411
15822         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15823
15824         # LU-4201
15825         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15826         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15827 }
15828 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15829
15830 test_220() { #LU-325
15831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15832         remote_ost_nodsh && skip "remote OST with nodsh"
15833         remote_mds_nodsh && skip "remote MDS with nodsh"
15834         remote_mgs_nodsh && skip "remote MGS with nodsh"
15835
15836         local OSTIDX=0
15837
15838         # create on MDT0000 so the last_id and next_id are correct
15839         mkdir $DIR/$tdir
15840         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15841         OST=${OST%_UUID}
15842
15843         # on the mdt's osc
15844         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15845         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15846                         osp.$mdtosc_proc1.prealloc_last_id)
15847         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15848                         osp.$mdtosc_proc1.prealloc_next_id)
15849
15850         $LFS df -i
15851
15852         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15853         #define OBD_FAIL_OST_ENOINO              0x229
15854         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15855         create_pool $FSNAME.$TESTNAME || return 1
15856         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15857
15858         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15859
15860         MDSOBJS=$((last_id - next_id))
15861         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15862
15863         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15864         echo "OST still has $count kbytes free"
15865
15866         echo "create $MDSOBJS files @next_id..."
15867         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15868
15869         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15870                         osp.$mdtosc_proc1.prealloc_last_id)
15871         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15872                         osp.$mdtosc_proc1.prealloc_next_id)
15873
15874         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15875         $LFS df -i
15876
15877         echo "cleanup..."
15878
15879         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15880         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15881
15882         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15883                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15884         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15885                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15886         echo "unlink $MDSOBJS files @$next_id..."
15887         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15888 }
15889 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15890
15891 test_221() {
15892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15893
15894         dd if=`which date` of=$MOUNT/date oflag=sync
15895         chmod +x $MOUNT/date
15896
15897         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15898         $LCTL set_param fail_loc=0x80001401
15899
15900         $MOUNT/date > /dev/null
15901         rm -f $MOUNT/date
15902 }
15903 run_test 221 "make sure fault and truncate race to not cause OOM"
15904
15905 test_222a () {
15906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15907
15908         rm -rf $DIR/$tdir
15909         test_mkdir $DIR/$tdir
15910         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15911         createmany -o $DIR/$tdir/$tfile 10
15912         cancel_lru_locks mdc
15913         cancel_lru_locks osc
15914         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15915         $LCTL set_param fail_loc=0x31a
15916         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15917         $LCTL set_param fail_loc=0
15918         rm -r $DIR/$tdir
15919 }
15920 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15921
15922 test_222b () {
15923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15924
15925         rm -rf $DIR/$tdir
15926         test_mkdir $DIR/$tdir
15927         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15928         createmany -o $DIR/$tdir/$tfile 10
15929         cancel_lru_locks mdc
15930         cancel_lru_locks osc
15931         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15932         $LCTL set_param fail_loc=0x31a
15933         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15934         $LCTL set_param fail_loc=0
15935 }
15936 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15937
15938 test_223 () {
15939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15940
15941         rm -rf $DIR/$tdir
15942         test_mkdir $DIR/$tdir
15943         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15944         createmany -o $DIR/$tdir/$tfile 10
15945         cancel_lru_locks mdc
15946         cancel_lru_locks osc
15947         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15948         $LCTL set_param fail_loc=0x31b
15949         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15950         $LCTL set_param fail_loc=0
15951         rm -r $DIR/$tdir
15952 }
15953 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15954
15955 test_224a() { # LU-1039, MRP-303
15956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15957
15958         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15959         $LCTL set_param fail_loc=0x508
15960         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15961         $LCTL set_param fail_loc=0
15962         df $DIR
15963 }
15964 run_test 224a "Don't panic on bulk IO failure"
15965
15966 test_224b() { # LU-1039, MRP-303
15967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15968
15969         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
15970         cancel_lru_locks osc
15971         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
15972         $LCTL set_param fail_loc=0x515
15973         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
15974         $LCTL set_param fail_loc=0
15975         df $DIR
15976 }
15977 run_test 224b "Don't panic on bulk IO failure"
15978
15979 test_224c() { # LU-6441
15980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15981         remote_mds_nodsh && skip "remote MDS with nodsh"
15982
15983         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15984         save_writethrough $p
15985         set_cache writethrough on
15986
15987         local pages_per_rpc=$($LCTL get_param \
15988                                 osc.*.max_pages_per_rpc)
15989         local at_max=$($LCTL get_param -n at_max)
15990         local timeout=$($LCTL get_param -n timeout)
15991         local test_at="at_max"
15992         local param_at="$FSNAME.sys.at_max"
15993         local test_timeout="timeout"
15994         local param_timeout="$FSNAME.sys.timeout"
15995
15996         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
15997
15998         set_persistent_param_and_check client "$test_at" "$param_at" 0
15999         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
16000
16001         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
16002         do_facet ost1 "$LCTL set_param fail_loc=0x520"
16003         $LFS setstripe -c 1 -i 0 $DIR/$tfile
16004         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
16005         sync
16006         do_facet ost1 "$LCTL set_param fail_loc=0"
16007
16008         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
16009         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
16010                 $timeout
16011
16012         $LCTL set_param -n $pages_per_rpc
16013         restore_lustre_params < $p
16014         rm -f $p
16015 }
16016 run_test 224c "Don't hang if one of md lost during large bulk RPC"
16017
16018 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
16019 test_225a () {
16020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16021         if [ -z ${MDSSURVEY} ]; then
16022                 skip_env "mds-survey not found"
16023         fi
16024         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16025                 skip "Need MDS version at least 2.2.51"
16026
16027         local mds=$(facet_host $SINGLEMDS)
16028         local target=$(do_nodes $mds 'lctl dl' |
16029                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16030
16031         local cmd1="file_count=1000 thrhi=4"
16032         local cmd2="dir_count=2 layer=mdd stripe_count=0"
16033         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16034         local cmd="$cmd1 $cmd2 $cmd3"
16035
16036         rm -f ${TMP}/mds_survey*
16037         echo + $cmd
16038         eval $cmd || error "mds-survey with zero-stripe failed"
16039         cat ${TMP}/mds_survey*
16040         rm -f ${TMP}/mds_survey*
16041 }
16042 run_test 225a "Metadata survey sanity with zero-stripe"
16043
16044 test_225b () {
16045         if [ -z ${MDSSURVEY} ]; then
16046                 skip_env "mds-survey not found"
16047         fi
16048         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16049                 skip "Need MDS version at least 2.2.51"
16050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16051         remote_mds_nodsh && skip "remote MDS with nodsh"
16052         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
16053                 skip_env "Need to mount OST to test"
16054         fi
16055
16056         local mds=$(facet_host $SINGLEMDS)
16057         local target=$(do_nodes $mds 'lctl dl' |
16058                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16059
16060         local cmd1="file_count=1000 thrhi=4"
16061         local cmd2="dir_count=2 layer=mdd stripe_count=1"
16062         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16063         local cmd="$cmd1 $cmd2 $cmd3"
16064
16065         rm -f ${TMP}/mds_survey*
16066         echo + $cmd
16067         eval $cmd || error "mds-survey with stripe_count failed"
16068         cat ${TMP}/mds_survey*
16069         rm -f ${TMP}/mds_survey*
16070 }
16071 run_test 225b "Metadata survey sanity with stripe_count = 1"
16072
16073 mcreate_path2fid () {
16074         local mode=$1
16075         local major=$2
16076         local minor=$3
16077         local name=$4
16078         local desc=$5
16079         local path=$DIR/$tdir/$name
16080         local fid
16081         local rc
16082         local fid_path
16083
16084         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
16085                 error "cannot create $desc"
16086
16087         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
16088         rc=$?
16089         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
16090
16091         fid_path=$($LFS fid2path $MOUNT $fid)
16092         rc=$?
16093         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
16094
16095         [ "$path" == "$fid_path" ] ||
16096                 error "fid2path returned $fid_path, expected $path"
16097
16098         echo "pass with $path and $fid"
16099 }
16100
16101 test_226a () {
16102         rm -rf $DIR/$tdir
16103         mkdir -p $DIR/$tdir
16104
16105         mcreate_path2fid 0010666 0 0 fifo "FIFO"
16106         mcreate_path2fid 0020666 1 3 null "character special file (null)"
16107         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
16108         mcreate_path2fid 0040666 0 0 dir "directory"
16109         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
16110         mcreate_path2fid 0100666 0 0 file "regular file"
16111         mcreate_path2fid 0120666 0 0 link "symbolic link"
16112         mcreate_path2fid 0140666 0 0 sock "socket"
16113 }
16114 run_test 226a "call path2fid and fid2path on files of all type"
16115
16116 test_226b () {
16117         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16118
16119         local MDTIDX=1
16120
16121         rm -rf $DIR/$tdir
16122         mkdir -p $DIR/$tdir
16123         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
16124                 error "create remote directory failed"
16125         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
16126         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
16127                                 "character special file (null)"
16128         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
16129                                 "character special file (no device)"
16130         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
16131         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
16132                                 "block special file (loop)"
16133         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
16134         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
16135         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
16136 }
16137 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
16138
16139 # LU-1299 Executing or running ldd on a truncated executable does not
16140 # cause an out-of-memory condition.
16141 test_227() {
16142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16143         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
16144
16145         dd if=$(which date) of=$MOUNT/date bs=1k count=1
16146         chmod +x $MOUNT/date
16147
16148         $MOUNT/date > /dev/null
16149         ldd $MOUNT/date > /dev/null
16150         rm -f $MOUNT/date
16151 }
16152 run_test 227 "running truncated executable does not cause OOM"
16153
16154 # LU-1512 try to reuse idle OI blocks
16155 test_228a() {
16156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16157         remote_mds_nodsh && skip "remote MDS with nodsh"
16158         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16159
16160         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16161         local myDIR=$DIR/$tdir
16162
16163         mkdir -p $myDIR
16164         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16165         $LCTL set_param fail_loc=0x80001002
16166         createmany -o $myDIR/t- 10000
16167         $LCTL set_param fail_loc=0
16168         # The guard is current the largest FID holder
16169         touch $myDIR/guard
16170         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16171                     tr -d '[')
16172         local IDX=$(($SEQ % 64))
16173
16174         do_facet $SINGLEMDS sync
16175         # Make sure journal flushed.
16176         sleep 6
16177         local blk1=$(do_facet $SINGLEMDS \
16178                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16179                      grep Blockcount | awk '{print $4}')
16180
16181         # Remove old files, some OI blocks will become idle.
16182         unlinkmany $myDIR/t- 10000
16183         # Create new files, idle OI blocks should be reused.
16184         createmany -o $myDIR/t- 2000
16185         do_facet $SINGLEMDS sync
16186         # Make sure journal flushed.
16187         sleep 6
16188         local blk2=$(do_facet $SINGLEMDS \
16189                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16190                      grep Blockcount | awk '{print $4}')
16191
16192         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16193 }
16194 run_test 228a "try to reuse idle OI blocks"
16195
16196 test_228b() {
16197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16198         remote_mds_nodsh && skip "remote MDS with nodsh"
16199         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16200
16201         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16202         local myDIR=$DIR/$tdir
16203
16204         mkdir -p $myDIR
16205         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16206         $LCTL set_param fail_loc=0x80001002
16207         createmany -o $myDIR/t- 10000
16208         $LCTL set_param fail_loc=0
16209         # The guard is current the largest FID holder
16210         touch $myDIR/guard
16211         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16212                     tr -d '[')
16213         local IDX=$(($SEQ % 64))
16214
16215         do_facet $SINGLEMDS sync
16216         # Make sure journal flushed.
16217         sleep 6
16218         local blk1=$(do_facet $SINGLEMDS \
16219                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16220                      grep Blockcount | awk '{print $4}')
16221
16222         # Remove old files, some OI blocks will become idle.
16223         unlinkmany $myDIR/t- 10000
16224
16225         # stop the MDT
16226         stop $SINGLEMDS || error "Fail to stop MDT."
16227         # remount the MDT
16228         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
16229
16230         df $MOUNT || error "Fail to df."
16231         # Create new files, idle OI blocks should be reused.
16232         createmany -o $myDIR/t- 2000
16233         do_facet $SINGLEMDS sync
16234         # Make sure journal flushed.
16235         sleep 6
16236         local blk2=$(do_facet $SINGLEMDS \
16237                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16238                      grep Blockcount | awk '{print $4}')
16239
16240         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16241 }
16242 run_test 228b "idle OI blocks can be reused after MDT restart"
16243
16244 #LU-1881
16245 test_228c() {
16246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16247         remote_mds_nodsh && skip "remote MDS with nodsh"
16248         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16249
16250         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16251         local myDIR=$DIR/$tdir
16252
16253         mkdir -p $myDIR
16254         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16255         $LCTL set_param fail_loc=0x80001002
16256         # 20000 files can guarantee there are index nodes in the OI file
16257         createmany -o $myDIR/t- 20000
16258         $LCTL set_param fail_loc=0
16259         # The guard is current the largest FID holder
16260         touch $myDIR/guard
16261         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16262                     tr -d '[')
16263         local IDX=$(($SEQ % 64))
16264
16265         do_facet $SINGLEMDS sync
16266         # Make sure journal flushed.
16267         sleep 6
16268         local blk1=$(do_facet $SINGLEMDS \
16269                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16270                      grep Blockcount | awk '{print $4}')
16271
16272         # Remove old files, some OI blocks will become idle.
16273         unlinkmany $myDIR/t- 20000
16274         rm -f $myDIR/guard
16275         # The OI file should become empty now
16276
16277         # Create new files, idle OI blocks should be reused.
16278         createmany -o $myDIR/t- 2000
16279         do_facet $SINGLEMDS sync
16280         # Make sure journal flushed.
16281         sleep 6
16282         local blk2=$(do_facet $SINGLEMDS \
16283                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16284                      grep Blockcount | awk '{print $4}')
16285
16286         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16287 }
16288 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
16289
16290 test_229() { # LU-2482, LU-3448
16291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16292         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
16293         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
16294                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
16295
16296         rm -f $DIR/$tfile
16297
16298         # Create a file with a released layout and stripe count 2.
16299         $MULTIOP $DIR/$tfile H2c ||
16300                 error "failed to create file with released layout"
16301
16302         $LFS getstripe -v $DIR/$tfile
16303
16304         local pattern=$($LFS getstripe -L $DIR/$tfile)
16305         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
16306
16307         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
16308                 error "getstripe"
16309         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
16310         stat $DIR/$tfile || error "failed to stat released file"
16311
16312         chown $RUNAS_ID $DIR/$tfile ||
16313                 error "chown $RUNAS_ID $DIR/$tfile failed"
16314
16315         chgrp $RUNAS_ID $DIR/$tfile ||
16316                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
16317
16318         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
16319         rm $DIR/$tfile || error "failed to remove released file"
16320 }
16321 run_test 229 "getstripe/stat/rm/attr changes work on released files"
16322
16323 test_230a() {
16324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16325         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16326         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16327                 skip "Need MDS version at least 2.11.52"
16328
16329         local MDTIDX=1
16330
16331         test_mkdir $DIR/$tdir
16332         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
16333         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
16334         [ $mdt_idx -ne 0 ] &&
16335                 error "create local directory on wrong MDT $mdt_idx"
16336
16337         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
16338                         error "create remote directory failed"
16339         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
16340         [ $mdt_idx -ne $MDTIDX ] &&
16341                 error "create remote directory on wrong MDT $mdt_idx"
16342
16343         createmany -o $DIR/$tdir/test_230/t- 10 ||
16344                 error "create files on remote directory failed"
16345         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
16346         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
16347         rm -r $DIR/$tdir || error "unlink remote directory failed"
16348 }
16349 run_test 230a "Create remote directory and files under the remote directory"
16350
16351 test_230b() {
16352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16353         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16354         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16355                 skip "Need MDS version at least 2.11.52"
16356
16357         local MDTIDX=1
16358         local mdt_index
16359         local i
16360         local file
16361         local pid
16362         local stripe_count
16363         local migrate_dir=$DIR/$tdir/migrate_dir
16364         local other_dir=$DIR/$tdir/other_dir
16365
16366         test_mkdir $DIR/$tdir
16367         test_mkdir -i0 -c1 $migrate_dir
16368         test_mkdir -i0 -c1 $other_dir
16369         for ((i=0; i<10; i++)); do
16370                 mkdir -p $migrate_dir/dir_${i}
16371                 createmany -o $migrate_dir/dir_${i}/f 10 ||
16372                         error "create files under remote dir failed $i"
16373         done
16374
16375         cp /etc/passwd $migrate_dir/$tfile
16376         cp /etc/passwd $other_dir/$tfile
16377         chattr +SAD $migrate_dir
16378         chattr +SAD $migrate_dir/$tfile
16379
16380         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16381         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16382         local old_dir_mode=$(stat -c%f $migrate_dir)
16383         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
16384
16385         mkdir -p $migrate_dir/dir_default_stripe2
16386         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
16387         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
16388
16389         mkdir -p $other_dir
16390         ln $migrate_dir/$tfile $other_dir/luna
16391         ln $migrate_dir/$tfile $migrate_dir/sofia
16392         ln $other_dir/$tfile $migrate_dir/david
16393         ln -s $migrate_dir/$tfile $other_dir/zachary
16394         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
16395         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
16396
16397         $LFS migrate -m $MDTIDX $migrate_dir ||
16398                 error "fails on migrating remote dir to MDT1"
16399
16400         echo "migratate to MDT1, then checking.."
16401         for ((i = 0; i < 10; i++)); do
16402                 for file in $(find $migrate_dir/dir_${i}); do
16403                         mdt_index=$($LFS getstripe -m $file)
16404                         [ $mdt_index == $MDTIDX ] ||
16405                                 error "$file is not on MDT${MDTIDX}"
16406                 done
16407         done
16408
16409         # the multiple link file should still in MDT0
16410         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
16411         [ $mdt_index == 0 ] ||
16412                 error "$file is not on MDT${MDTIDX}"
16413
16414         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16415         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16416                 error " expect $old_dir_flag get $new_dir_flag"
16417
16418         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16419         [ "$old_file_flag" = "$new_file_flag" ] ||
16420                 error " expect $old_file_flag get $new_file_flag"
16421
16422         local new_dir_mode=$(stat -c%f $migrate_dir)
16423         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16424                 error "expect mode $old_dir_mode get $new_dir_mode"
16425
16426         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16427         [ "$old_file_mode" = "$new_file_mode" ] ||
16428                 error "expect mode $old_file_mode get $new_file_mode"
16429
16430         diff /etc/passwd $migrate_dir/$tfile ||
16431                 error "$tfile different after migration"
16432
16433         diff /etc/passwd $other_dir/luna ||
16434                 error "luna different after migration"
16435
16436         diff /etc/passwd $migrate_dir/sofia ||
16437                 error "sofia different after migration"
16438
16439         diff /etc/passwd $migrate_dir/david ||
16440                 error "david different after migration"
16441
16442         diff /etc/passwd $other_dir/zachary ||
16443                 error "zachary different after migration"
16444
16445         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16446                 error "${tfile}_ln different after migration"
16447
16448         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16449                 error "${tfile}_ln_other different after migration"
16450
16451         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
16452         [ $stripe_count = 2 ] ||
16453                 error "dir strpe_count $d != 2 after migration."
16454
16455         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
16456         [ $stripe_count = 2 ] ||
16457                 error "file strpe_count $d != 2 after migration."
16458
16459         #migrate back to MDT0
16460         MDTIDX=0
16461
16462         $LFS migrate -m $MDTIDX $migrate_dir ||
16463                 error "fails on migrating remote dir to MDT0"
16464
16465         echo "migrate back to MDT0, checking.."
16466         for file in $(find $migrate_dir); do
16467                 mdt_index=$($LFS getstripe -m $file)
16468                 [ $mdt_index == $MDTIDX ] ||
16469                         error "$file is not on MDT${MDTIDX}"
16470         done
16471
16472         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16473         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16474                 error " expect $old_dir_flag get $new_dir_flag"
16475
16476         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16477         [ "$old_file_flag" = "$new_file_flag" ] ||
16478                 error " expect $old_file_flag get $new_file_flag"
16479
16480         local new_dir_mode=$(stat -c%f $migrate_dir)
16481         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16482                 error "expect mode $old_dir_mode get $new_dir_mode"
16483
16484         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16485         [ "$old_file_mode" = "$new_file_mode" ] ||
16486                 error "expect mode $old_file_mode get $new_file_mode"
16487
16488         diff /etc/passwd ${migrate_dir}/$tfile ||
16489                 error "$tfile different after migration"
16490
16491         diff /etc/passwd ${other_dir}/luna ||
16492                 error "luna different after migration"
16493
16494         diff /etc/passwd ${migrate_dir}/sofia ||
16495                 error "sofia different after migration"
16496
16497         diff /etc/passwd ${other_dir}/zachary ||
16498                 error "zachary different after migration"
16499
16500         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16501                 error "${tfile}_ln different after migration"
16502
16503         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16504                 error "${tfile}_ln_other different after migration"
16505
16506         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
16507         [ $stripe_count = 2 ] ||
16508                 error "dir strpe_count $d != 2 after migration."
16509
16510         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
16511         [ $stripe_count = 2 ] ||
16512                 error "file strpe_count $d != 2 after migration."
16513
16514         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16515 }
16516 run_test 230b "migrate directory"
16517
16518 test_230c() {
16519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16520         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16521         remote_mds_nodsh && skip "remote MDS with nodsh"
16522         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16523                 skip "Need MDS version at least 2.11.52"
16524
16525         local MDTIDX=1
16526         local total=3
16527         local mdt_index
16528         local file
16529         local migrate_dir=$DIR/$tdir/migrate_dir
16530
16531         #If migrating directory fails in the middle, all entries of
16532         #the directory is still accessiable.
16533         test_mkdir $DIR/$tdir
16534         test_mkdir -i0 -c1 $migrate_dir
16535         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
16536         stat $migrate_dir
16537         createmany -o $migrate_dir/f $total ||
16538                 error "create files under ${migrate_dir} failed"
16539
16540         # fail after migrating top dir, and this will fail only once, so the
16541         # first sub file migration will fail (currently f3), others succeed.
16542         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16543         do_facet mds1 lctl set_param fail_loc=0x1801
16544         local t=$(ls $migrate_dir | wc -l)
16545         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
16546                 error "migrate should fail"
16547         local u=$(ls $migrate_dir | wc -l)
16548         [ "$u" == "$t" ] || error "$u != $t during migration"
16549
16550         # add new dir/file should succeed
16551         mkdir $migrate_dir/dir ||
16552                 error "mkdir failed under migrating directory"
16553         touch $migrate_dir/file ||
16554                 error "create file failed under migrating directory"
16555
16556         # add file with existing name should fail
16557         for file in $migrate_dir/f*; do
16558                 stat $file > /dev/null || error "stat $file failed"
16559                 $OPENFILE -f O_CREAT:O_EXCL $file &&
16560                         error "open(O_CREAT|O_EXCL) $file should fail"
16561                 $MULTIOP $file m && error "create $file should fail"
16562                 touch $DIR/$tdir/remote_dir/$tfile ||
16563                         error "touch $tfile failed"
16564                 ln $DIR/$tdir/remote_dir/$tfile $file &&
16565                         error "link $file should fail"
16566                 mdt_index=$($LFS getstripe -m $file)
16567                 if [ $mdt_index == 0 ]; then
16568                         # file failed to migrate is not allowed to rename to
16569                         mv $DIR/$tdir/remote_dir/$tfile $file &&
16570                                 error "rename to $file should fail"
16571                 else
16572                         mv $DIR/$tdir/remote_dir/$tfile $file ||
16573                                 error "rename to $file failed"
16574                 fi
16575                 echo hello >> $file || error "write $file failed"
16576         done
16577
16578         # resume migration with different options should fail
16579         $LFS migrate -m 0 $migrate_dir &&
16580                 error "migrate -m 0 $migrate_dir should fail"
16581
16582         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
16583                 error "migrate -c 2 $migrate_dir should fail"
16584
16585         # resume migration should succeed
16586         $LFS migrate -m $MDTIDX $migrate_dir ||
16587                 error "migrate $migrate_dir failed"
16588
16589         echo "Finish migration, then checking.."
16590         for file in $(find $migrate_dir); do
16591                 mdt_index=$($LFS getstripe -m $file)
16592                 [ $mdt_index == $MDTIDX ] ||
16593                         error "$file is not on MDT${MDTIDX}"
16594         done
16595
16596         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16597 }
16598 run_test 230c "check directory accessiblity if migration failed"
16599
16600 test_230d() {
16601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16602         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16603         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16604                 skip "Need MDS version at least 2.11.52"
16605         # LU-11235
16606         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
16607
16608         local migrate_dir=$DIR/$tdir/migrate_dir
16609         local old_index
16610         local new_index
16611         local old_count
16612         local new_count
16613         local new_hash
16614         local mdt_index
16615         local i
16616         local j
16617
16618         old_index=$((RANDOM % MDSCOUNT))
16619         old_count=$((MDSCOUNT - old_index))
16620         new_index=$((RANDOM % MDSCOUNT))
16621         new_count=$((MDSCOUNT - new_index))
16622         new_hash="all_char"
16623
16624         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
16625         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
16626
16627         test_mkdir $DIR/$tdir
16628         test_mkdir -i $old_index -c $old_count $migrate_dir
16629
16630         for ((i=0; i<100; i++)); do
16631                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
16632                 createmany -o $migrate_dir/dir_${i}/f 100 ||
16633                         error "create files under remote dir failed $i"
16634         done
16635
16636         echo -n "Migrate from MDT$old_index "
16637         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
16638         echo -n "to MDT$new_index"
16639         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16640         echo
16641
16642         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16643         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16644                 error "migrate remote dir error"
16645
16646         echo "Finish migration, then checking.."
16647         for file in $(find $migrate_dir); do
16648                 mdt_index=$($LFS getstripe -m $file)
16649                 if [ $mdt_index -lt $new_index ] ||
16650                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16651                         error "$file is on MDT$mdt_index"
16652                 fi
16653         done
16654
16655         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16656 }
16657 run_test 230d "check migrate big directory"
16658
16659 test_230e() {
16660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16661         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16662         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16663                 skip "Need MDS version at least 2.11.52"
16664
16665         local i
16666         local j
16667         local a_fid
16668         local b_fid
16669
16670         mkdir -p $DIR/$tdir
16671         mkdir $DIR/$tdir/migrate_dir
16672         mkdir $DIR/$tdir/other_dir
16673         touch $DIR/$tdir/migrate_dir/a
16674         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16675         ls $DIR/$tdir/other_dir
16676
16677         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16678                 error "migrate dir fails"
16679
16680         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16681         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16682
16683         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16684         [ $mdt_index == 0 ] || error "a is not on MDT0"
16685
16686         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16687                 error "migrate dir fails"
16688
16689         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16690         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16691
16692         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16693         [ $mdt_index == 1 ] || error "a is not on MDT1"
16694
16695         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16696         [ $mdt_index == 1 ] || error "b is not on MDT1"
16697
16698         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16699         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16700
16701         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16702
16703         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16704 }
16705 run_test 230e "migrate mulitple local link files"
16706
16707 test_230f() {
16708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16709         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16710         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16711                 skip "Need MDS version at least 2.11.52"
16712
16713         local a_fid
16714         local ln_fid
16715
16716         mkdir -p $DIR/$tdir
16717         mkdir $DIR/$tdir/migrate_dir
16718         $LFS mkdir -i1 $DIR/$tdir/other_dir
16719         touch $DIR/$tdir/migrate_dir/a
16720         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16721         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16722         ls $DIR/$tdir/other_dir
16723
16724         # a should be migrated to MDT1, since no other links on MDT0
16725         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16726                 error "#1 migrate dir fails"
16727         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16728         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16729         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16730         [ $mdt_index == 1 ] || error "a is not on MDT1"
16731
16732         # a should stay on MDT1, because it is a mulitple link file
16733         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16734                 error "#2 migrate dir fails"
16735         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16736         [ $mdt_index == 1 ] || error "a is not on MDT1"
16737
16738         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16739                 error "#3 migrate dir fails"
16740
16741         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16742         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16743         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16744
16745         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16746         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16747
16748         # a should be migrated to MDT0, since no other links on MDT1
16749         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16750                 error "#4 migrate dir fails"
16751         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16752         [ $mdt_index == 0 ] || error "a is not on MDT0"
16753
16754         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16755 }
16756 run_test 230f "migrate mulitple remote link files"
16757
16758 test_230g() {
16759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16760         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16761         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16762                 skip "Need MDS version at least 2.11.52"
16763
16764         mkdir -p $DIR/$tdir/migrate_dir
16765
16766         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16767                 error "migrating dir to non-exist MDT succeeds"
16768         true
16769 }
16770 run_test 230g "migrate dir to non-exist MDT"
16771
16772 test_230h() {
16773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16774         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16775         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16776                 skip "Need MDS version at least 2.11.52"
16777
16778         local mdt_index
16779
16780         mkdir -p $DIR/$tdir/migrate_dir
16781
16782         $LFS migrate -m1 $DIR &&
16783                 error "migrating mountpoint1 should fail"
16784
16785         $LFS migrate -m1 $DIR/$tdir/.. &&
16786                 error "migrating mountpoint2 should fail"
16787
16788         # same as mv
16789         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16790                 error "migrating $tdir/migrate_dir/.. should fail"
16791
16792         true
16793 }
16794 run_test 230h "migrate .. and root"
16795
16796 test_230i() {
16797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16798         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16799         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16800                 skip "Need MDS version at least 2.11.52"
16801
16802         mkdir -p $DIR/$tdir/migrate_dir
16803
16804         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16805                 error "migration fails with a tailing slash"
16806
16807         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16808                 error "migration fails with two tailing slashes"
16809 }
16810 run_test 230i "lfs migrate -m tolerates trailing slashes"
16811
16812 test_230j() {
16813         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16814         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16815                 skip "Need MDS version at least 2.11.52"
16816
16817         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16818         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16819                 error "create $tfile failed"
16820         cat /etc/passwd > $DIR/$tdir/$tfile
16821
16822         $LFS migrate -m 1 $DIR/$tdir
16823
16824         cmp /etc/passwd $DIR/$tdir/$tfile ||
16825                 error "DoM file mismatch after migration"
16826 }
16827 run_test 230j "DoM file data not changed after dir migration"
16828
16829 test_230k() {
16830         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16831         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16832                 skip "Need MDS version at least 2.11.56"
16833
16834         local total=20
16835         local files_on_starting_mdt=0
16836
16837         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16838         $LFS getdirstripe $DIR/$tdir
16839         for i in $(seq $total); do
16840                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16841                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16842                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16843         done
16844
16845         echo "$files_on_starting_mdt files on MDT0"
16846
16847         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16848         $LFS getdirstripe $DIR/$tdir
16849
16850         files_on_starting_mdt=0
16851         for i in $(seq $total); do
16852                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16853                         error "file $tfile.$i mismatch after migration"
16854                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16855                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16856         done
16857
16858         echo "$files_on_starting_mdt files on MDT1 after migration"
16859         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16860
16861         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16862         $LFS getdirstripe $DIR/$tdir
16863
16864         files_on_starting_mdt=0
16865         for i in $(seq $total); do
16866                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16867                         error "file $tfile.$i mismatch after 2nd migration"
16868                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16869                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16870         done
16871
16872         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16873         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16874
16875         true
16876 }
16877 run_test 230k "file data not changed after dir migration"
16878
16879 test_230l() {
16880         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16881         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16882                 skip "Need MDS version at least 2.11.56"
16883
16884         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16885         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16886                 error "create files under remote dir failed $i"
16887         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16888 }
16889 run_test 230l "readdir between MDTs won't crash"
16890
16891 test_231a()
16892 {
16893         # For simplicity this test assumes that max_pages_per_rpc
16894         # is the same across all OSCs
16895         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16896         local bulk_size=$((max_pages * PAGE_SIZE))
16897         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16898                                        head -n 1)
16899
16900         mkdir -p $DIR/$tdir
16901         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16902                 error "failed to set stripe with -S ${brw_size}M option"
16903
16904         # clear the OSC stats
16905         $LCTL set_param osc.*.stats=0 &>/dev/null
16906         stop_writeback
16907
16908         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
16909         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
16910                 oflag=direct &>/dev/null || error "dd failed"
16911
16912         sync; sleep 1; sync # just to be safe
16913         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
16914         if [ x$nrpcs != "x1" ]; then
16915                 $LCTL get_param osc.*.stats
16916                 error "found $nrpcs ost_write RPCs, not 1 as expected"
16917         fi
16918
16919         start_writeback
16920         # Drop the OSC cache, otherwise we will read from it
16921         cancel_lru_locks osc
16922
16923         # clear the OSC stats
16924         $LCTL set_param osc.*.stats=0 &>/dev/null
16925
16926         # Client reads $bulk_size.
16927         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
16928                 iflag=direct &>/dev/null || error "dd failed"
16929
16930         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
16931         if [ x$nrpcs != "x1" ]; then
16932                 $LCTL get_param osc.*.stats
16933                 error "found $nrpcs ost_read RPCs, not 1 as expected"
16934         fi
16935 }
16936 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
16937
16938 test_231b() {
16939         mkdir -p $DIR/$tdir
16940         local i
16941         for i in {0..1023}; do
16942                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
16943                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
16944                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
16945         done
16946         sync
16947 }
16948 run_test 231b "must not assert on fully utilized OST request buffer"
16949
16950 test_232a() {
16951         mkdir -p $DIR/$tdir
16952         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16953
16954         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16955         do_facet ost1 $LCTL set_param fail_loc=0x31c
16956
16957         # ignore dd failure
16958         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
16959
16960         do_facet ost1 $LCTL set_param fail_loc=0
16961         umount_client $MOUNT || error "umount failed"
16962         mount_client $MOUNT || error "mount failed"
16963         stop ost1 || error "cannot stop ost1"
16964         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16965 }
16966 run_test 232a "failed lock should not block umount"
16967
16968 test_232b() {
16969         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
16970                 skip "Need MDS version at least 2.10.58"
16971
16972         mkdir -p $DIR/$tdir
16973         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16974         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
16975         sync
16976         cancel_lru_locks osc
16977
16978         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16979         do_facet ost1 $LCTL set_param fail_loc=0x31c
16980
16981         # ignore failure
16982         $LFS data_version $DIR/$tdir/$tfile || true
16983
16984         do_facet ost1 $LCTL set_param fail_loc=0
16985         umount_client $MOUNT || error "umount failed"
16986         mount_client $MOUNT || error "mount failed"
16987         stop ost1 || error "cannot stop ost1"
16988         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16989 }
16990 run_test 232b "failed data version lock should not block umount"
16991
16992 test_233a() {
16993         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
16994                 skip "Need MDS version at least 2.3.64"
16995         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16996
16997         local fid=$($LFS path2fid $MOUNT)
16998
16999         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17000                 error "cannot access $MOUNT using its FID '$fid'"
17001 }
17002 run_test 233a "checking that OBF of the FS root succeeds"
17003
17004 test_233b() {
17005         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
17006                 skip "Need MDS version at least 2.5.90"
17007         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17008
17009         local fid=$($LFS path2fid $MOUNT/.lustre)
17010
17011         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17012                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
17013
17014         fid=$($LFS path2fid $MOUNT/.lustre/fid)
17015         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17016                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
17017 }
17018 run_test 233b "checking that OBF of the FS .lustre succeeds"
17019
17020 test_234() {
17021         local p="$TMP/sanityN-$TESTNAME.parameters"
17022         save_lustre_params client "llite.*.xattr_cache" > $p
17023         lctl set_param llite.*.xattr_cache 1 ||
17024                 skip_env "xattr cache is not supported"
17025
17026         mkdir -p $DIR/$tdir || error "mkdir failed"
17027         touch $DIR/$tdir/$tfile || error "touch failed"
17028         # OBD_FAIL_LLITE_XATTR_ENOMEM
17029         $LCTL set_param fail_loc=0x1405
17030         getfattr -n user.attr $DIR/$tdir/$tfile &&
17031                 error "getfattr should have failed with ENOMEM"
17032         $LCTL set_param fail_loc=0x0
17033         rm -rf $DIR/$tdir
17034
17035         restore_lustre_params < $p
17036         rm -f $p
17037 }
17038 run_test 234 "xattr cache should not crash on ENOMEM"
17039
17040 test_235() {
17041         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
17042                 skip "Need MDS version at least 2.4.52"
17043
17044         flock_deadlock $DIR/$tfile
17045         local RC=$?
17046         case $RC in
17047                 0)
17048                 ;;
17049                 124) error "process hangs on a deadlock"
17050                 ;;
17051                 *) error "error executing flock_deadlock $DIR/$tfile"
17052                 ;;
17053         esac
17054 }
17055 run_test 235 "LU-1715: flock deadlock detection does not work properly"
17056
17057 #LU-2935
17058 test_236() {
17059         check_swap_layouts_support
17060
17061         local ref1=/etc/passwd
17062         local ref2=/etc/group
17063         local file1=$DIR/$tdir/f1
17064         local file2=$DIR/$tdir/f2
17065
17066         test_mkdir -c1 $DIR/$tdir
17067         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
17068         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
17069         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
17070         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
17071         local fd=$(free_fd)
17072         local cmd="exec $fd<>$file2"
17073         eval $cmd
17074         rm $file2
17075         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
17076                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
17077         cmd="exec $fd>&-"
17078         eval $cmd
17079         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17080
17081         #cleanup
17082         rm -rf $DIR/$tdir
17083 }
17084 run_test 236 "Layout swap on open unlinked file"
17085
17086 # LU-4659 linkea consistency
17087 test_238() {
17088         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17089                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17090                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17091                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17092
17093         touch $DIR/$tfile
17094         ln $DIR/$tfile $DIR/$tfile.lnk
17095         touch $DIR/$tfile.new
17096         mv $DIR/$tfile.new $DIR/$tfile
17097         local fid1=$($LFS path2fid $DIR/$tfile)
17098         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
17099         local path1=$($LFS fid2path $FSNAME "$fid1")
17100         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
17101         local path2=$($LFS fid2path $FSNAME "$fid2")
17102         [ $tfile.lnk == $path2 ] ||
17103                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
17104         rm -f $DIR/$tfile*
17105 }
17106 run_test 238 "Verify linkea consistency"
17107
17108 test_239A() { # was test_239
17109         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
17110                 skip "Need MDS version at least 2.5.60"
17111
17112         local list=$(comma_list $(mdts_nodes))
17113
17114         mkdir -p $DIR/$tdir
17115         createmany -o $DIR/$tdir/f- 5000
17116         unlinkmany $DIR/$tdir/f- 5000
17117         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
17118                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
17119         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
17120                         osp.*MDT*.sync_in_flight" | calc_sum)
17121         [ "$changes" -eq 0 ] || error "$changes not synced"
17122 }
17123 run_test 239A "osp_sync test"
17124
17125 test_239a() { #LU-5297
17126         remote_mds_nodsh && skip "remote MDS with nodsh"
17127
17128         touch $DIR/$tfile
17129         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
17130         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
17131         chgrp $RUNAS_GID $DIR/$tfile
17132         wait_delete_completed
17133 }
17134 run_test 239a "process invalid osp sync record correctly"
17135
17136 test_239b() { #LU-5297
17137         remote_mds_nodsh && skip "remote MDS with nodsh"
17138
17139         touch $DIR/$tfile1
17140         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
17141         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
17142         chgrp $RUNAS_GID $DIR/$tfile1
17143         wait_delete_completed
17144         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17145         touch $DIR/$tfile2
17146         chgrp $RUNAS_GID $DIR/$tfile2
17147         wait_delete_completed
17148 }
17149 run_test 239b "process osp sync record with ENOMEM error correctly"
17150
17151 test_240() {
17152         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17153         remote_mds_nodsh && skip "remote MDS with nodsh"
17154
17155         mkdir -p $DIR/$tdir
17156
17157         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
17158                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
17159         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
17160                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
17161
17162         umount_client $MOUNT || error "umount failed"
17163         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
17164         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
17165         mount_client $MOUNT || error "failed to mount client"
17166
17167         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
17168         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
17169 }
17170 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
17171
17172 test_241_bio() {
17173         local count=$1
17174         local bsize=$2
17175
17176         for LOOP in $(seq $count); do
17177                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
17178                 cancel_lru_locks $OSC || true
17179         done
17180 }
17181
17182 test_241_dio() {
17183         local count=$1
17184         local bsize=$2
17185
17186         for LOOP in $(seq $1); do
17187                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
17188                         2>/dev/null
17189         done
17190 }
17191
17192 test_241a() { # was test_241
17193         local bsize=$PAGE_SIZE
17194
17195         (( bsize < 40960 )) && bsize=40960
17196         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17197         ls -la $DIR/$tfile
17198         cancel_lru_locks $OSC
17199         test_241_bio 1000 $bsize &
17200         PID=$!
17201         test_241_dio 1000 $bsize
17202         wait $PID
17203 }
17204 run_test 241a "bio vs dio"
17205
17206 test_241b() {
17207         local bsize=$PAGE_SIZE
17208
17209         (( bsize < 40960 )) && bsize=40960
17210         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17211         ls -la $DIR/$tfile
17212         test_241_dio 1000 $bsize &
17213         PID=$!
17214         test_241_dio 1000 $bsize
17215         wait $PID
17216 }
17217 run_test 241b "dio vs dio"
17218
17219 test_242() {
17220         remote_mds_nodsh && skip "remote MDS with nodsh"
17221
17222         mkdir -p $DIR/$tdir
17223         touch $DIR/$tdir/$tfile
17224
17225         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
17226         do_facet mds1 lctl set_param fail_loc=0x105
17227         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
17228
17229         do_facet mds1 lctl set_param fail_loc=0
17230         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
17231 }
17232 run_test 242 "mdt_readpage failure should not cause directory unreadable"
17233
17234 test_243()
17235 {
17236         test_mkdir $DIR/$tdir
17237         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
17238 }
17239 run_test 243 "various group lock tests"
17240
17241 test_244a()
17242 {
17243         test_mkdir $DIR/$tdir
17244         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
17245         sendfile_grouplock $DIR/$tdir/$tfile || \
17246                 error "sendfile+grouplock failed"
17247         rm -rf $DIR/$tdir
17248 }
17249 run_test 244a "sendfile with group lock tests"
17250
17251 test_244b()
17252 {
17253         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17254
17255         local threads=50
17256         local size=$((1024*1024))
17257
17258         test_mkdir $DIR/$tdir
17259         for i in $(seq 1 $threads); do
17260                 local file=$DIR/$tdir/file_$((i / 10))
17261                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
17262                 local pids[$i]=$!
17263         done
17264         for i in $(seq 1 $threads); do
17265                 wait ${pids[$i]}
17266         done
17267 }
17268 run_test 244b "multi-threaded write with group lock"
17269
17270 test_245() {
17271         local flagname="multi_mod_rpcs"
17272         local connect_data_name="max_mod_rpcs"
17273         local out
17274
17275         # check if multiple modify RPCs flag is set
17276         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
17277                 grep "connect_flags:")
17278         echo "$out"
17279
17280         echo "$out" | grep -qw $flagname
17281         if [ $? -ne 0 ]; then
17282                 echo "connect flag $flagname is not set"
17283                 return
17284         fi
17285
17286         # check if multiple modify RPCs data is set
17287         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
17288         echo "$out"
17289
17290         echo "$out" | grep -qw $connect_data_name ||
17291                 error "import should have connect data $connect_data_name"
17292 }
17293 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
17294
17295 test_246() { # LU-7371
17296         remote_ost_nodsh && skip "remote OST with nodsh"
17297         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
17298                 skip "Need OST version >= 2.7.62"
17299
17300         do_facet ost1 $LCTL set_param fail_val=4095
17301 #define OBD_FAIL_OST_READ_SIZE          0x234
17302         do_facet ost1 $LCTL set_param fail_loc=0x234
17303         $LFS setstripe $DIR/$tfile -i 0 -c 1
17304         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
17305         cancel_lru_locks $FSNAME-OST0000
17306         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
17307 }
17308 run_test 246 "Read file of size 4095 should return right length"
17309
17310 cleanup_247() {
17311         local submount=$1
17312
17313         trap 0
17314         umount_client $submount
17315         rmdir $submount
17316 }
17317
17318 test_247a() {
17319         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17320                 grep -q subtree ||
17321                 skip_env "Fileset feature is not supported"
17322
17323         local submount=${MOUNT}_$tdir
17324
17325         mkdir $MOUNT/$tdir
17326         mkdir -p $submount || error "mkdir $submount failed"
17327         FILESET="$FILESET/$tdir" mount_client $submount ||
17328                 error "mount $submount failed"
17329         trap "cleanup_247 $submount" EXIT
17330         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
17331         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
17332                 error "read $MOUNT/$tdir/$tfile failed"
17333         cleanup_247 $submount
17334 }
17335 run_test 247a "mount subdir as fileset"
17336
17337 test_247b() {
17338         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17339                 skip_env "Fileset feature is not supported"
17340
17341         local submount=${MOUNT}_$tdir
17342
17343         rm -rf $MOUNT/$tdir
17344         mkdir -p $submount || error "mkdir $submount failed"
17345         SKIP_FILESET=1
17346         FILESET="$FILESET/$tdir" mount_client $submount &&
17347                 error "mount $submount should fail"
17348         rmdir $submount
17349 }
17350 run_test 247b "mount subdir that dose not exist"
17351
17352 test_247c() {
17353         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17354                 skip_env "Fileset feature is not supported"
17355
17356         local submount=${MOUNT}_$tdir
17357
17358         mkdir -p $MOUNT/$tdir/dir1
17359         mkdir -p $submount || error "mkdir $submount failed"
17360         trap "cleanup_247 $submount" EXIT
17361         FILESET="$FILESET/$tdir" mount_client $submount ||
17362                 error "mount $submount failed"
17363         local fid=$($LFS path2fid $MOUNT/)
17364         $LFS fid2path $submount $fid && error "fid2path should fail"
17365         cleanup_247 $submount
17366 }
17367 run_test 247c "running fid2path outside root"
17368
17369 test_247d() {
17370         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17371                 skip "Fileset feature is not supported"
17372
17373         local submount=${MOUNT}_$tdir
17374
17375         mkdir -p $MOUNT/$tdir/dir1
17376         mkdir -p $submount || error "mkdir $submount failed"
17377         FILESET="$FILESET/$tdir" mount_client $submount ||
17378                 error "mount $submount failed"
17379         trap "cleanup_247 $submount" EXIT
17380         local fid=$($LFS path2fid $submount/dir1)
17381         $LFS fid2path $submount $fid || error "fid2path should succeed"
17382         cleanup_247 $submount
17383 }
17384 run_test 247d "running fid2path inside root"
17385
17386 # LU-8037
17387 test_247e() {
17388         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17389                 grep -q subtree ||
17390                 skip "Fileset feature is not supported"
17391
17392         local submount=${MOUNT}_$tdir
17393
17394         mkdir $MOUNT/$tdir
17395         mkdir -p $submount || error "mkdir $submount failed"
17396         FILESET="$FILESET/.." mount_client $submount &&
17397                 error "mount $submount should fail"
17398         rmdir $submount
17399 }
17400 run_test 247e "mount .. as fileset"
17401
17402 test_248() {
17403         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
17404         [ -z "$fast_read_sav" ] && skip "no fast read support"
17405
17406         # create a large file for fast read verification
17407         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
17408
17409         # make sure the file is created correctly
17410         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
17411                 { rm -f $DIR/$tfile; skip "file creation error"; }
17412
17413         echo "Test 1: verify that fast read is 4 times faster on cache read"
17414
17415         # small read with fast read enabled
17416         $LCTL set_param -n llite.*.fast_read=1
17417         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17418                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17419                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17420         # small read with fast read disabled
17421         $LCTL set_param -n llite.*.fast_read=0
17422         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17423                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17424                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17425
17426         # verify that fast read is 4 times faster for cache read
17427         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
17428                 error_not_in_vm "fast read was not 4 times faster: " \
17429                            "$t_fast vs $t_slow"
17430
17431         echo "Test 2: verify the performance between big and small read"
17432         $LCTL set_param -n llite.*.fast_read=1
17433
17434         # 1k non-cache read
17435         cancel_lru_locks osc
17436         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17437                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17438                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17439
17440         # 1M non-cache read
17441         cancel_lru_locks osc
17442         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17443                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17444                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17445
17446         # verify that big IO is not 4 times faster than small IO
17447         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
17448                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
17449
17450         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
17451         rm -f $DIR/$tfile
17452 }
17453 run_test 248 "fast read verification"
17454
17455 test_249() { # LU-7890
17456         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
17457                 skip "Need at least version 2.8.54"
17458
17459         rm -f $DIR/$tfile
17460         $LFS setstripe -c 1 $DIR/$tfile
17461         # Offset 2T == 4k * 512M
17462         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
17463                 error "dd to 2T offset failed"
17464 }
17465 run_test 249 "Write above 2T file size"
17466
17467 test_250() {
17468         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
17469          && skip "no 16TB file size limit on ZFS"
17470
17471         $LFS setstripe -c 1 $DIR/$tfile
17472         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
17473         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
17474         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
17475         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
17476                 conv=notrunc,fsync && error "append succeeded"
17477         return 0
17478 }
17479 run_test 250 "Write above 16T limit"
17480
17481 test_251() {
17482         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
17483
17484         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
17485         #Skip once - writing the first stripe will succeed
17486         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17487         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
17488                 error "short write happened"
17489
17490         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17491         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
17492                 error "short read happened"
17493
17494         rm -f $DIR/$tfile
17495 }
17496 run_test 251 "Handling short read and write correctly"
17497
17498 test_252() {
17499         remote_mds_nodsh && skip "remote MDS with nodsh"
17500         remote_ost_nodsh && skip "remote OST with nodsh"
17501         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
17502                 skip_env "ldiskfs only test"
17503         fi
17504
17505         local tgt
17506         local dev
17507         local out
17508         local uuid
17509         local num
17510         local gen
17511
17512         # check lr_reader on OST0000
17513         tgt=ost1
17514         dev=$(facet_device $tgt)
17515         out=$(do_facet $tgt $LR_READER $dev)
17516         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17517         echo "$out"
17518         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
17519         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
17520                 error "Invalid uuid returned by $LR_READER on target $tgt"
17521         echo -e "uuid returned by $LR_READER is '$uuid'\n"
17522
17523         # check lr_reader -c on MDT0000
17524         tgt=mds1
17525         dev=$(facet_device $tgt)
17526         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
17527                 skip "$LR_READER does not support additional options"
17528         fi
17529         out=$(do_facet $tgt $LR_READER -c $dev)
17530         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17531         echo "$out"
17532         num=$(echo "$out" | grep -c "mdtlov")
17533         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
17534                 error "Invalid number of mdtlov clients returned by $LR_READER"
17535         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
17536
17537         # check lr_reader -cr on MDT0000
17538         out=$(do_facet $tgt $LR_READER -cr $dev)
17539         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17540         echo "$out"
17541         echo "$out" | grep -q "^reply_data:$" ||
17542                 error "$LR_READER should have returned 'reply_data' section"
17543         num=$(echo "$out" | grep -c "client_generation")
17544         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
17545 }
17546 run_test 252 "check lr_reader tool"
17547
17548 test_253() {
17549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17550         remote_mds_nodsh && skip "remote MDS with nodsh"
17551         remote_mgs_nodsh && skip "remote MGS with nodsh"
17552
17553         local ostidx=0
17554         local rc=0
17555         local ost_name=$(ostname_from_index $ostidx)
17556
17557         # on the mdt's osc
17558         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
17559         do_facet $SINGLEMDS $LCTL get_param -n \
17560                 osp.$mdtosc_proc1.reserved_mb_high ||
17561                 skip  "remote MDS does not support reserved_mb_high"
17562
17563         rm -rf $DIR/$tdir
17564         wait_mds_ost_sync
17565         wait_delete_completed
17566         mkdir $DIR/$tdir
17567
17568         pool_add $TESTNAME || error "Pool creation failed"
17569         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
17570
17571         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
17572                 error "Setstripe failed"
17573
17574         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
17575
17576         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
17577                     grep "watermarks")
17578         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
17579
17580         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17581                         osp.$mdtosc_proc1.prealloc_status)
17582         echo "prealloc_status $oa_status"
17583
17584         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
17585                 error "File creation should fail"
17586
17587         #object allocation was stopped, but we still able to append files
17588         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
17589                 oflag=append || error "Append failed"
17590
17591         rm -f $DIR/$tdir/$tfile.0
17592
17593         # For this test, we want to delete the files we created to go out of
17594         # space but leave the watermark, so we remain nearly out of space
17595         ost_watermarks_enospc_delete_files $tfile $ostidx
17596
17597         wait_delete_completed
17598
17599         sleep_maxage
17600
17601         for i in $(seq 10 12); do
17602                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
17603                         2>/dev/null || error "File creation failed after rm"
17604         done
17605
17606         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17607                         osp.$mdtosc_proc1.prealloc_status)
17608         echo "prealloc_status $oa_status"
17609
17610         if (( oa_status != 0 )); then
17611                 error "Object allocation still disable after rm"
17612         fi
17613 }
17614 run_test 253 "Check object allocation limit"
17615
17616 test_254() {
17617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17618         remote_mds_nodsh && skip "remote MDS with nodsh"
17619         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17620                 skip "MDS does not support changelog_size"
17621
17622         local cl_user
17623         local MDT0=$(facet_svc $SINGLEMDS)
17624
17625         changelog_register || error "changelog_register failed"
17626
17627         changelog_clear 0 || error "changelog_clear failed"
17628
17629         local size1=$(do_facet $SINGLEMDS \
17630                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17631         echo "Changelog size $size1"
17632
17633         rm -rf $DIR/$tdir
17634         $LFS mkdir -i 0 $DIR/$tdir
17635         # change something
17636         mkdir -p $DIR/$tdir/pics/2008/zachy
17637         touch $DIR/$tdir/pics/2008/zachy/timestamp
17638         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17639         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17640         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17641         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17642         rm $DIR/$tdir/pics/desktop.jpg
17643
17644         local size2=$(do_facet $SINGLEMDS \
17645                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17646         echo "Changelog size after work $size2"
17647
17648         (( $size2 > $size1 )) ||
17649                 error "new Changelog size=$size2 less than old size=$size1"
17650 }
17651 run_test 254 "Check changelog size"
17652
17653 ladvise_no_type()
17654 {
17655         local type=$1
17656         local file=$2
17657
17658         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17659                 awk -F: '{print $2}' | grep $type > /dev/null
17660         if [ $? -ne 0 ]; then
17661                 return 0
17662         fi
17663         return 1
17664 }
17665
17666 ladvise_no_ioctl()
17667 {
17668         local file=$1
17669
17670         lfs ladvise -a willread $file > /dev/null 2>&1
17671         if [ $? -eq 0 ]; then
17672                 return 1
17673         fi
17674
17675         lfs ladvise -a willread $file 2>&1 |
17676                 grep "Inappropriate ioctl for device" > /dev/null
17677         if [ $? -eq 0 ]; then
17678                 return 0
17679         fi
17680         return 1
17681 }
17682
17683 percent() {
17684         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17685 }
17686
17687 # run a random read IO workload
17688 # usage: random_read_iops <filename> <filesize> <iosize>
17689 random_read_iops() {
17690         local file=$1
17691         local fsize=$2
17692         local iosize=${3:-4096}
17693
17694         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17695                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17696 }
17697
17698 drop_file_oss_cache() {
17699         local file="$1"
17700         local nodes="$2"
17701
17702         $LFS ladvise -a dontneed $file 2>/dev/null ||
17703                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17704 }
17705
17706 ladvise_willread_performance()
17707 {
17708         local repeat=10
17709         local average_origin=0
17710         local average_cache=0
17711         local average_ladvise=0
17712
17713         for ((i = 1; i <= $repeat; i++)); do
17714                 echo "Iter $i/$repeat: reading without willread hint"
17715                 cancel_lru_locks osc
17716                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17717                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17718                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17719                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17720
17721                 cancel_lru_locks osc
17722                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17723                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17724                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17725
17726                 cancel_lru_locks osc
17727                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17728                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17729                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17730                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17731                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17732         done
17733         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17734         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17735         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17736
17737         speedup_cache=$(percent $average_cache $average_origin)
17738         speedup_ladvise=$(percent $average_ladvise $average_origin)
17739
17740         echo "Average uncached read: $average_origin"
17741         echo "Average speedup with OSS cached read: " \
17742                 "$average_cache = +$speedup_cache%"
17743         echo "Average speedup with ladvise willread: " \
17744                 "$average_ladvise = +$speedup_ladvise%"
17745
17746         local lowest_speedup=20
17747         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17748                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17749                         "got $average_cache%. Skipping ladvise willread check."
17750                 return 0
17751         fi
17752
17753         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17754         # it is still good to run until then to exercise 'ladvise willread'
17755         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17756                 [ "$ost1_FSTYPE" = "zfs" ] &&
17757                 echo "osd-zfs does not support dontneed or drop_caches" &&
17758                 return 0
17759
17760         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17761         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17762                 error_not_in_vm "Speedup with willread is less than " \
17763                         "$lowest_speedup%, got $average_ladvise%"
17764 }
17765
17766 test_255a() {
17767         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17768                 skip "lustre < 2.8.54 does not support ladvise "
17769         remote_ost_nodsh && skip "remote OST with nodsh"
17770
17771         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17772
17773         ladvise_no_type willread $DIR/$tfile &&
17774                 skip "willread ladvise is not supported"
17775
17776         ladvise_no_ioctl $DIR/$tfile &&
17777                 skip "ladvise ioctl is not supported"
17778
17779         local size_mb=100
17780         local size=$((size_mb * 1048576))
17781         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17782                 error "dd to $DIR/$tfile failed"
17783
17784         lfs ladvise -a willread $DIR/$tfile ||
17785                 error "Ladvise failed with no range argument"
17786
17787         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17788                 error "Ladvise failed with no -l or -e argument"
17789
17790         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17791                 error "Ladvise failed with only -e argument"
17792
17793         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17794                 error "Ladvise failed with only -l argument"
17795
17796         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17797                 error "End offset should not be smaller than start offset"
17798
17799         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17800                 error "End offset should not be equal to start offset"
17801
17802         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17803                 error "Ladvise failed with overflowing -s argument"
17804
17805         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17806                 error "Ladvise failed with overflowing -e argument"
17807
17808         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17809                 error "Ladvise failed with overflowing -l argument"
17810
17811         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17812                 error "Ladvise succeeded with conflicting -l and -e arguments"
17813
17814         echo "Synchronous ladvise should wait"
17815         local delay=4
17816 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17817         do_nodes $(comma_list $(osts_nodes)) \
17818                 $LCTL set_param fail_val=$delay fail_loc=0x237
17819
17820         local start_ts=$SECONDS
17821         lfs ladvise -a willread $DIR/$tfile ||
17822                 error "Ladvise failed with no range argument"
17823         local end_ts=$SECONDS
17824         local inteval_ts=$((end_ts - start_ts))
17825
17826         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17827                 error "Synchronous advice didn't wait reply"
17828         fi
17829
17830         echo "Asynchronous ladvise shouldn't wait"
17831         local start_ts=$SECONDS
17832         lfs ladvise -a willread -b $DIR/$tfile ||
17833                 error "Ladvise failed with no range argument"
17834         local end_ts=$SECONDS
17835         local inteval_ts=$((end_ts - start_ts))
17836
17837         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17838                 error "Asynchronous advice blocked"
17839         fi
17840
17841         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
17842         ladvise_willread_performance
17843 }
17844 run_test 255a "check 'lfs ladvise -a willread'"
17845
17846 facet_meminfo() {
17847         local facet=$1
17848         local info=$2
17849
17850         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
17851 }
17852
17853 test_255b() {
17854         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17855                 skip "lustre < 2.8.54 does not support ladvise "
17856         remote_ost_nodsh && skip "remote OST with nodsh"
17857
17858         lfs setstripe -c 1 -i 0 $DIR/$tfile
17859
17860         ladvise_no_type dontneed $DIR/$tfile &&
17861                 skip "dontneed ladvise is not supported"
17862
17863         ladvise_no_ioctl $DIR/$tfile &&
17864                 skip "ladvise ioctl is not supported"
17865
17866         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17867                 [ "$ost1_FSTYPE" = "zfs" ] &&
17868                 skip "zfs-osd does not support 'ladvise dontneed'"
17869
17870         local size_mb=100
17871         local size=$((size_mb * 1048576))
17872         # In order to prevent disturbance of other processes, only check 3/4
17873         # of the memory usage
17874         local kibibytes=$((size_mb * 1024 * 3 / 4))
17875
17876         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17877                 error "dd to $DIR/$tfile failed"
17878
17879         #force write to complete before dropping OST cache & checking memory
17880         sync
17881
17882         local total=$(facet_meminfo ost1 MemTotal)
17883         echo "Total memory: $total KiB"
17884
17885         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
17886         local before_read=$(facet_meminfo ost1 Cached)
17887         echo "Cache used before read: $before_read KiB"
17888
17889         lfs ladvise -a willread $DIR/$tfile ||
17890                 error "Ladvise willread failed"
17891         local after_read=$(facet_meminfo ost1 Cached)
17892         echo "Cache used after read: $after_read KiB"
17893
17894         lfs ladvise -a dontneed $DIR/$tfile ||
17895                 error "Ladvise dontneed again failed"
17896         local no_read=$(facet_meminfo ost1 Cached)
17897         echo "Cache used after dontneed ladvise: $no_read KiB"
17898
17899         if [ $total -lt $((before_read + kibibytes)) ]; then
17900                 echo "Memory is too small, abort checking"
17901                 return 0
17902         fi
17903
17904         if [ $((before_read + kibibytes)) -gt $after_read ]; then
17905                 error "Ladvise willread should use more memory" \
17906                         "than $kibibytes KiB"
17907         fi
17908
17909         if [ $((no_read + kibibytes)) -gt $after_read ]; then
17910                 error "Ladvise dontneed should release more memory" \
17911                         "than $kibibytes KiB"
17912         fi
17913 }
17914 run_test 255b "check 'lfs ladvise -a dontneed'"
17915
17916 test_255c() {
17917         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
17918                 skip "lustre < 2.10.50 does not support lockahead"
17919
17920         local count
17921         local new_count
17922         local difference
17923         local i
17924         local rc
17925
17926         test_mkdir -p $DIR/$tdir
17927         $LFS setstripe -i 0 -c 1 $DIR/$tdir
17928
17929         #test 10 returns only success/failure
17930         i=10
17931         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17932         rc=$?
17933         if [ $rc -eq 255 ]; then
17934                 error "Ladvise test${i} failed, ${rc}"
17935         fi
17936
17937         #test 11 counts lock enqueue requests, all others count new locks
17938         i=11
17939         count=$(do_facet ost1 \
17940                 $LCTL get_param -n ost.OSS.ost.stats)
17941         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
17942
17943         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17944         rc=$?
17945         if [ $rc -eq 255 ]; then
17946                 error "Ladvise test${i} failed, ${rc}"
17947         fi
17948
17949         new_count=$(do_facet ost1 \
17950                 $LCTL get_param -n ost.OSS.ost.stats)
17951         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
17952                    awk '{ print $2 }')
17953
17954         difference="$((new_count - count))"
17955         if [ $difference -ne $rc ]; then
17956                 error "Ladvise test${i}, bad enqueue count, returned " \
17957                       "${rc}, actual ${difference}"
17958         fi
17959
17960         for i in $(seq 12 21); do
17961                 # If we do not do this, we run the risk of having too many
17962                 # locks and starting lock cancellation while we are checking
17963                 # lock counts.
17964                 cancel_lru_locks osc
17965
17966                 count=$($LCTL get_param -n \
17967                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17968
17969                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
17970                 rc=$?
17971                 if [ $rc -eq 255 ]; then
17972                         error "Ladvise test ${i} failed, ${rc}"
17973                 fi
17974
17975                 new_count=$($LCTL get_param -n \
17976                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17977                 difference="$((new_count - count))"
17978
17979                 # Test 15 output is divided by 100 to map down to valid return
17980                 if [ $i -eq 15 ]; then
17981                         rc="$((rc * 100))"
17982                 fi
17983
17984                 if [ $difference -ne $rc ]; then
17985                         error "Ladvise test ${i}, bad lock count, returned " \
17986                               "${rc}, actual ${difference}"
17987                 fi
17988         done
17989
17990         #test 22 returns only success/failure
17991         i=22
17992         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17993         rc=$?
17994         if [ $rc -eq 255 ]; then
17995                 error "Ladvise test${i} failed, ${rc}"
17996         fi
17997 }
17998 run_test 255c "suite of ladvise lockahead tests"
17999
18000 test_256() {
18001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18002         remote_mds_nodsh && skip "remote MDS with nodsh"
18003         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18004         changelog_users $SINGLEMDS | grep "^cl" &&
18005                 skip "active changelog user"
18006
18007         local cl_user
18008         local cat_sl
18009         local mdt_dev
18010
18011         mdt_dev=$(mdsdevname 1)
18012         echo $mdt_dev
18013
18014         changelog_register || error "changelog_register failed"
18015
18016         rm -rf $DIR/$tdir
18017         mkdir -p $DIR/$tdir
18018
18019         changelog_clear 0 || error "changelog_clear failed"
18020
18021         # change something
18022         touch $DIR/$tdir/{1..10}
18023
18024         # stop the MDT
18025         stop $SINGLEMDS || error "Fail to stop MDT"
18026
18027         # remount the MDT
18028
18029         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
18030
18031         #after mount new plainllog is used
18032         touch $DIR/$tdir/{11..19}
18033         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
18034         stack_trap "rm -f $tmpfile"
18035         cat_sl=$(do_facet $SINGLEMDS "sync; \
18036                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18037                  llog_reader $tmpfile | grep -c type=1064553b")
18038         do_facet $SINGLEMDS llog_reader $tmpfile
18039
18040         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
18041
18042         changelog_clear 0 || error "changelog_clear failed"
18043
18044         cat_sl=$(do_facet $SINGLEMDS "sync; \
18045                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18046                  llog_reader $tmpfile | grep -c type=1064553b")
18047
18048         if (( cat_sl == 2 )); then
18049                 error "Empty plain llog was not deleted from changelog catalog"
18050         elif (( cat_sl != 1 )); then
18051                 error "Active plain llog shouldn't be deleted from catalog"
18052         fi
18053 }
18054 run_test 256 "Check llog delete for empty and not full state"
18055
18056 test_257() {
18057         remote_mds_nodsh && skip "remote MDS with nodsh"
18058         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
18059                 skip "Need MDS version at least 2.8.55"
18060
18061         test_mkdir $DIR/$tdir
18062
18063         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
18064                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
18065         stat $DIR/$tdir
18066
18067 #define OBD_FAIL_MDS_XATTR_REP                  0x161
18068         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18069         local facet=mds$((mdtidx + 1))
18070         set_nodes_failloc $(facet_active_host $facet) 0x80000161
18071         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
18072
18073         stop $facet || error "stop MDS failed"
18074         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
18075                 error "start MDS fail"
18076         wait_recovery_complete $facet
18077 }
18078 run_test 257 "xattr locks are not lost"
18079
18080 # Verify we take the i_mutex when security requires it
18081 test_258a() {
18082 #define OBD_FAIL_IMUTEX_SEC 0x141c
18083         $LCTL set_param fail_loc=0x141c
18084         touch $DIR/$tfile
18085         chmod u+s $DIR/$tfile
18086         chmod a+rwx $DIR/$tfile
18087         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18088         RC=$?
18089         if [ $RC -ne 0 ]; then
18090                 error "error, failed to take i_mutex, rc=$?"
18091         fi
18092         rm -f $DIR/$tfile
18093 }
18094 run_test 258a "verify i_mutex security behavior when suid attributes is set"
18095
18096 # Verify we do NOT take the i_mutex in the normal case
18097 test_258b() {
18098 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
18099         $LCTL set_param fail_loc=0x141d
18100         touch $DIR/$tfile
18101         chmod a+rwx $DIR
18102         chmod a+rw $DIR/$tfile
18103         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18104         RC=$?
18105         if [ $RC -ne 0 ]; then
18106                 error "error, took i_mutex unnecessarily, rc=$?"
18107         fi
18108         rm -f $DIR/$tfile
18109
18110 }
18111 run_test 258b "verify i_mutex security behavior"
18112
18113 test_259() {
18114         local file=$DIR/$tfile
18115         local before
18116         local after
18117
18118         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18119
18120         stack_trap "rm -f $file" EXIT
18121
18122         wait_delete_completed
18123         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18124         echo "before: $before"
18125
18126         $LFS setstripe -i 0 -c 1 $file
18127         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
18128         sync_all_data
18129         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18130         echo "after write: $after"
18131
18132 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
18133         do_facet ost1 $LCTL set_param fail_loc=0x2301
18134         $TRUNCATE $file 0
18135         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18136         echo "after truncate: $after"
18137
18138         stop ost1
18139         do_facet ost1 $LCTL set_param fail_loc=0
18140         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18141         sleep 2
18142         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18143         echo "after restart: $after"
18144         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
18145                 error "missing truncate?"
18146
18147         return 0
18148 }
18149 run_test 259 "crash at delayed truncate"
18150
18151 test_260() {
18152 #define OBD_FAIL_MDC_CLOSE               0x806
18153         $LCTL set_param fail_loc=0x80000806
18154         touch $DIR/$tfile
18155
18156 }
18157 run_test 260 "Check mdc_close fail"
18158
18159 ### Data-on-MDT sanity tests ###
18160 test_270a() {
18161         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18162                 skip "Need MDS version at least 2.10.55 for DoM"
18163
18164         # create DoM file
18165         local dom=$DIR/$tdir/dom_file
18166         local tmp=$DIR/$tdir/tmp_file
18167
18168         mkdir -p $DIR/$tdir
18169
18170         # basic checks for DoM component creation
18171         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
18172                 error "Can set MDT layout to non-first entry"
18173
18174         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
18175                 error "Can define multiple entries as MDT layout"
18176
18177         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
18178
18179         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
18180         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
18181         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
18182
18183         local mdtidx=$($LFS getstripe -m $dom)
18184         local mdtname=MDT$(printf %04x $mdtidx)
18185         local facet=mds$((mdtidx + 1))
18186         local space_check=1
18187
18188         # Skip free space checks with ZFS
18189         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
18190
18191         # write
18192         sync
18193         local size_tmp=$((65536 * 3))
18194         local mdtfree1=$(do_facet $facet \
18195                          lctl get_param -n osd*.*$mdtname.kbytesfree)
18196
18197         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18198         # check also direct IO along write
18199         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
18200         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18201         sync
18202         cmp $tmp $dom || error "file data is different"
18203         [ $(stat -c%s $dom) == $size_tmp ] ||
18204                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18205         if [ $space_check == 1 ]; then
18206                 local mdtfree2=$(do_facet $facet \
18207                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
18208
18209                 # increase in usage from by $size_tmp
18210                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18211                         error "MDT free space wrong after write: " \
18212                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18213         fi
18214
18215         # truncate
18216         local size_dom=10000
18217
18218         $TRUNCATE $dom $size_dom
18219         [ $(stat -c%s $dom) == $size_dom ] ||
18220                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
18221         if [ $space_check == 1 ]; then
18222                 mdtfree1=$(do_facet $facet \
18223                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18224                 # decrease in usage from $size_tmp to new $size_dom
18225                 [ $(($mdtfree1 - $mdtfree2)) -ge \
18226                   $(((size_tmp - size_dom) / 1024)) ] ||
18227                         error "MDT free space is wrong after truncate: " \
18228                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
18229         fi
18230
18231         # append
18232         cat $tmp >> $dom
18233         sync
18234         size_dom=$((size_dom + size_tmp))
18235         [ $(stat -c%s $dom) == $size_dom ] ||
18236                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
18237         if [ $space_check == 1 ]; then
18238                 mdtfree2=$(do_facet $facet \
18239                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18240                 # increase in usage by $size_tmp from previous
18241                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18242                         error "MDT free space is wrong after append: " \
18243                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18244         fi
18245
18246         # delete
18247         rm $dom
18248         if [ $space_check == 1 ]; then
18249                 mdtfree1=$(do_facet $facet \
18250                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18251                 # decrease in usage by $size_dom from previous
18252                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
18253                         error "MDT free space is wrong after removal: " \
18254                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
18255         fi
18256
18257         # combined striping
18258         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
18259                 error "Can't create DoM + OST striping"
18260
18261         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
18262         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18263         # check also direct IO along write
18264         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18265         sync
18266         cmp $tmp $dom || error "file data is different"
18267         [ $(stat -c%s $dom) == $size_tmp ] ||
18268                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18269         rm $dom $tmp
18270
18271         return 0
18272 }
18273 run_test 270a "DoM: basic functionality tests"
18274
18275 test_270b() {
18276         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18277                 skip "Need MDS version at least 2.10.55"
18278
18279         local dom=$DIR/$tdir/dom_file
18280         local max_size=1048576
18281
18282         mkdir -p $DIR/$tdir
18283         $LFS setstripe -E $max_size -L mdt $dom
18284
18285         # truncate over the limit
18286         $TRUNCATE $dom $(($max_size + 1)) &&
18287                 error "successful truncate over the maximum size"
18288         # write over the limit
18289         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
18290                 error "successful write over the maximum size"
18291         # append over the limit
18292         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
18293         echo "12345" >> $dom && error "successful append over the maximum size"
18294         rm $dom
18295
18296         return 0
18297 }
18298 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
18299
18300 test_270c() {
18301         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18302                 skip "Need MDS version at least 2.10.55"
18303
18304         mkdir -p $DIR/$tdir
18305         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18306
18307         # check files inherit DoM EA
18308         touch $DIR/$tdir/first
18309         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
18310                 error "bad pattern"
18311         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
18312                 error "bad stripe count"
18313         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
18314                 error "bad stripe size"
18315
18316         # check directory inherits DoM EA and uses it as default
18317         mkdir $DIR/$tdir/subdir
18318         touch $DIR/$tdir/subdir/second
18319         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
18320                 error "bad pattern in sub-directory"
18321         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
18322                 error "bad stripe count in sub-directory"
18323         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
18324                 error "bad stripe size in sub-directory"
18325         return 0
18326 }
18327 run_test 270c "DoM: DoM EA inheritance tests"
18328
18329 test_270d() {
18330         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18331                 skip "Need MDS version at least 2.10.55"
18332
18333         mkdir -p $DIR/$tdir
18334         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18335
18336         # inherit default DoM striping
18337         mkdir $DIR/$tdir/subdir
18338         touch $DIR/$tdir/subdir/f1
18339
18340         # change default directory striping
18341         $LFS setstripe -c 1 $DIR/$tdir/subdir
18342         touch $DIR/$tdir/subdir/f2
18343         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
18344                 error "wrong default striping in file 2"
18345         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
18346                 error "bad pattern in file 2"
18347         return 0
18348 }
18349 run_test 270d "DoM: change striping from DoM to RAID0"
18350
18351 test_270e() {
18352         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18353                 skip "Need MDS version at least 2.10.55"
18354
18355         mkdir -p $DIR/$tdir/dom
18356         mkdir -p $DIR/$tdir/norm
18357         DOMFILES=20
18358         NORMFILES=10
18359         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
18360         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
18361
18362         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
18363         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
18364
18365         # find DoM files by layout
18366         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
18367         [ $NUM -eq  $DOMFILES ] ||
18368                 error "lfs find -L: found $NUM, expected $DOMFILES"
18369         echo "Test 1: lfs find 20 DOM files by layout: OK"
18370
18371         # there should be 1 dir with default DOM striping
18372         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
18373         [ $NUM -eq  1 ] ||
18374                 error "lfs find -L: found $NUM, expected 1 dir"
18375         echo "Test 2: lfs find 1 DOM dir by layout: OK"
18376
18377         # find DoM files by stripe size
18378         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
18379         [ $NUM -eq  $DOMFILES ] ||
18380                 error "lfs find -S: found $NUM, expected $DOMFILES"
18381         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
18382
18383         # find files by stripe offset except DoM files
18384         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
18385         [ $NUM -eq  $NORMFILES ] ||
18386                 error "lfs find -i: found $NUM, expected $NORMFILES"
18387         echo "Test 5: lfs find no DOM files by stripe index: OK"
18388         return 0
18389 }
18390 run_test 270e "DoM: lfs find with DoM files test"
18391
18392 test_270f() {
18393         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18394                 skip "Need MDS version at least 2.10.55"
18395
18396         local mdtname=${FSNAME}-MDT0000-mdtlov
18397         local dom=$DIR/$tdir/dom_file
18398         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
18399                                                 lod.$mdtname.dom_stripesize)
18400         local dom_limit=131072
18401
18402         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
18403         local dom_current=$(do_facet mds1 $LCTL get_param -n \
18404                                                 lod.$mdtname.dom_stripesize)
18405         [ ${dom_limit} -eq ${dom_current} ] ||
18406                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
18407
18408         $LFS mkdir -i 0 -c 1 $DIR/$tdir
18409         $LFS setstripe -d $DIR/$tdir
18410         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
18411                 error "Can't set directory default striping"
18412
18413         # exceed maximum stripe size
18414         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18415                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
18416         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
18417                 error "Able to create DoM component size more than LOD limit"
18418
18419         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
18420         dom_current=$(do_facet mds1 $LCTL get_param -n \
18421                                                 lod.$mdtname.dom_stripesize)
18422         [ 0 -eq ${dom_current} ] ||
18423                 error "Can't set zero DoM stripe limit"
18424         rm $dom
18425
18426         # attempt to create DoM file on server with disabled DoM should
18427         # remove DoM entry from layout and be succeed
18428         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
18429                 error "Can't create DoM file (DoM is disabled)"
18430         [ $($LFS getstripe -L $dom) == "mdt" ] &&
18431                 error "File has DoM component while DoM is disabled"
18432         rm $dom
18433
18434         # attempt to create DoM file with only DoM stripe should return error
18435         $LFS setstripe -E $dom_limit -L mdt $dom &&
18436                 error "Able to create DoM-only file while DoM is disabled"
18437
18438         # too low values to be aligned with smallest stripe size 64K
18439         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
18440         dom_current=$(do_facet mds1 $LCTL get_param -n \
18441                                                 lod.$mdtname.dom_stripesize)
18442         [ 30000 -eq ${dom_current} ] &&
18443                 error "Can set too small DoM stripe limit"
18444
18445         # 64K is a minimal stripe size in Lustre, expect limit of that size
18446         [ 65536 -eq ${dom_current} ] ||
18447                 error "Limit is not set to 64K but ${dom_current}"
18448
18449         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
18450         dom_current=$(do_facet mds1 $LCTL get_param -n \
18451                                                 lod.$mdtname.dom_stripesize)
18452         echo $dom_current
18453         [ 2147483648 -eq ${dom_current} ] &&
18454                 error "Can set too large DoM stripe limit"
18455
18456         do_facet mds1 $LCTL set_param -n \
18457                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
18458         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18459                 error "Can't create DoM component size after limit change"
18460         do_facet mds1 $LCTL set_param -n \
18461                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
18462         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
18463                 error "Can't create DoM file after limit decrease"
18464         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
18465                 error "Can create big DoM component after limit decrease"
18466         touch ${dom}_def ||
18467                 error "Can't create file with old default layout"
18468
18469         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
18470         return 0
18471 }
18472 run_test 270f "DoM: maximum DoM stripe size checks"
18473
18474 test_271a() {
18475         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18476                 skip "Need MDS version at least 2.10.55"
18477
18478         local dom=$DIR/$tdir/dom
18479
18480         mkdir -p $DIR/$tdir
18481
18482         $LFS setstripe -E 1024K -L mdt $dom
18483
18484         lctl set_param -n mdc.*.stats=clear
18485         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18486         cat $dom > /dev/null
18487         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
18488         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
18489         ls $dom
18490         rm -f $dom
18491 }
18492 run_test 271a "DoM: data is cached for read after write"
18493
18494 test_271b() {
18495         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18496                 skip "Need MDS version at least 2.10.55"
18497
18498         local dom=$DIR/$tdir/dom
18499
18500         mkdir -p $DIR/$tdir
18501
18502         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18503
18504         lctl set_param -n mdc.*.stats=clear
18505         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18506         cancel_lru_locks mdc
18507         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
18508         # second stat to check size is cached on client
18509         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
18510         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18511         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
18512         rm -f $dom
18513 }
18514 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
18515
18516 test_271ba() {
18517         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18518                 skip "Need MDS version at least 2.10.55"
18519
18520         local dom=$DIR/$tdir/dom
18521
18522         mkdir -p $DIR/$tdir
18523
18524         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18525
18526         lctl set_param -n mdc.*.stats=clear
18527         lctl set_param -n osc.*.stats=clear
18528         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
18529         cancel_lru_locks mdc
18530         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18531         # second stat to check size is cached on client
18532         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18533         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18534         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
18535         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
18536         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
18537         rm -f $dom
18538 }
18539 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
18540
18541
18542 get_mdc_stats() {
18543         local mdtidx=$1
18544         local param=$2
18545         local mdt=MDT$(printf %04x $mdtidx)
18546
18547         if [ -z $param ]; then
18548                 lctl get_param -n mdc.*$mdt*.stats
18549         else
18550                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
18551         fi
18552 }
18553
18554 test_271c() {
18555         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18556                 skip "Need MDS version at least 2.10.55"
18557
18558         local dom=$DIR/$tdir/dom
18559
18560         mkdir -p $DIR/$tdir
18561
18562         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18563
18564         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18565         local facet=mds$((mdtidx + 1))
18566
18567         cancel_lru_locks mdc
18568         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
18569         createmany -o $dom 1000
18570         lctl set_param -n mdc.*.stats=clear
18571         smalliomany -w $dom 1000 200
18572         get_mdc_stats $mdtidx
18573         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18574         # Each file has 1 open, 1 IO enqueues, total 2000
18575         # but now we have also +1 getxattr for security.capability, total 3000
18576         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
18577         unlinkmany $dom 1000
18578
18579         cancel_lru_locks mdc
18580         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
18581         createmany -o $dom 1000
18582         lctl set_param -n mdc.*.stats=clear
18583         smalliomany -w $dom 1000 200
18584         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18585         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
18586         # for OPEN and IO lock.
18587         [ $((enq - enq_2)) -ge 1000 ] ||
18588                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
18589         unlinkmany $dom 1000
18590         return 0
18591 }
18592 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
18593
18594 cleanup_271def_tests() {
18595         trap 0
18596         rm -f $1
18597 }
18598
18599 test_271d() {
18600         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18601                 skip "Need MDS version at least 2.10.57"
18602
18603         local dom=$DIR/$tdir/dom
18604         local tmp=$TMP/$tfile
18605         trap "cleanup_271def_tests $tmp" EXIT
18606
18607         mkdir -p $DIR/$tdir
18608
18609         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18610
18611         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18612
18613         cancel_lru_locks mdc
18614         dd if=/dev/urandom of=$tmp bs=1000 count=1
18615         dd if=$tmp of=$dom bs=1000 count=1
18616         cancel_lru_locks mdc
18617
18618         cat /etc/hosts >> $tmp
18619         lctl set_param -n mdc.*.stats=clear
18620
18621         # append data to the same file it should update local page
18622         echo "Append to the same page"
18623         cat /etc/hosts >> $dom
18624         local num=$(get_mdc_stats $mdtidx ost_read)
18625         local ra=$(get_mdc_stats $mdtidx req_active)
18626         local rw=$(get_mdc_stats $mdtidx req_waittime)
18627
18628         [ -z $num ] || error "$num READ RPC occured"
18629         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18630         echo "... DONE"
18631
18632         # compare content
18633         cmp $tmp $dom || error "file miscompare"
18634
18635         cancel_lru_locks mdc
18636         lctl set_param -n mdc.*.stats=clear
18637
18638         echo "Open and read file"
18639         cat $dom > /dev/null
18640         local num=$(get_mdc_stats $mdtidx ost_read)
18641         local ra=$(get_mdc_stats $mdtidx req_active)
18642         local rw=$(get_mdc_stats $mdtidx req_waittime)
18643
18644         [ -z $num ] || error "$num READ RPC occured"
18645         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18646         echo "... DONE"
18647
18648         # compare content
18649         cmp $tmp $dom || error "file miscompare"
18650
18651         return 0
18652 }
18653 run_test 271d "DoM: read on open (1K file in reply buffer)"
18654
18655 test_271f() {
18656         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18657                 skip "Need MDS version at least 2.10.57"
18658
18659         local dom=$DIR/$tdir/dom
18660         local tmp=$TMP/$tfile
18661         trap "cleanup_271def_tests $tmp" EXIT
18662
18663         mkdir -p $DIR/$tdir
18664
18665         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18666
18667         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18668
18669         cancel_lru_locks mdc
18670         dd if=/dev/urandom of=$tmp bs=265000 count=1
18671         dd if=$tmp of=$dom bs=265000 count=1
18672         cancel_lru_locks mdc
18673         cat /etc/hosts >> $tmp
18674         lctl set_param -n mdc.*.stats=clear
18675
18676         echo "Append to the same page"
18677         cat /etc/hosts >> $dom
18678         local num=$(get_mdc_stats $mdtidx ost_read)
18679         local ra=$(get_mdc_stats $mdtidx req_active)
18680         local rw=$(get_mdc_stats $mdtidx req_waittime)
18681
18682         [ -z $num ] || error "$num READ RPC occured"
18683         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18684         echo "... DONE"
18685
18686         # compare content
18687         cmp $tmp $dom || error "file miscompare"
18688
18689         cancel_lru_locks mdc
18690         lctl set_param -n mdc.*.stats=clear
18691
18692         echo "Open and read file"
18693         cat $dom > /dev/null
18694         local num=$(get_mdc_stats $mdtidx ost_read)
18695         local ra=$(get_mdc_stats $mdtidx req_active)
18696         local rw=$(get_mdc_stats $mdtidx req_waittime)
18697
18698         [ -z $num ] && num=0
18699         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18700         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18701         echo "... DONE"
18702
18703         # compare content
18704         cmp $tmp $dom || error "file miscompare"
18705
18706         return 0
18707 }
18708 run_test 271f "DoM: read on open (200K file and read tail)"
18709
18710 test_271g() {
18711         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18712                 skip "Skipping due to old client or server version"
18713
18714         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18715         # to get layout
18716         $CHECKSTAT -t file $DIR1/$tfile
18717
18718         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18719         MULTIOP_PID=$!
18720         sleep 1
18721         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18722         $LCTL set_param fail_loc=0x80000314
18723         rm $DIR1/$tfile || error "Unlink fails"
18724         RC=$?
18725         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18726         [ $RC -eq 0 ] || error "Failed write to stale object"
18727 }
18728 run_test 271g "Discard DoM data vs client flush race"
18729
18730 test_272a() {
18731         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18732                 skip "Need MDS version at least 2.11.50"
18733
18734         local dom=$DIR/$tdir/dom
18735         mkdir -p $DIR/$tdir
18736
18737         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18738         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18739                 error "failed to write data into $dom"
18740         local old_md5=$(md5sum $dom)
18741
18742         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18743                 error "failed to migrate to the same DoM component"
18744
18745         local new_md5=$(md5sum $dom)
18746
18747         [ "$old_md5" == "$new_md5" ] ||
18748                 error "md5sum differ: $old_md5, $new_md5"
18749
18750         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18751                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18752 }
18753 run_test 272a "DoM migration: new layout with the same DOM component"
18754
18755 test_272b() {
18756         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18757                 skip "Need MDS version at least 2.11.50"
18758
18759         local dom=$DIR/$tdir/dom
18760         mkdir -p $DIR/$tdir
18761         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18762
18763         local mdtidx=$($LFS getstripe -m $dom)
18764         local mdtname=MDT$(printf %04x $mdtidx)
18765         local facet=mds$((mdtidx + 1))
18766
18767         local mdtfree1=$(do_facet $facet \
18768                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18769         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18770                 error "failed to write data into $dom"
18771         local old_md5=$(md5sum $dom)
18772         cancel_lru_locks mdc
18773         local mdtfree1=$(do_facet $facet \
18774                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18775
18776         $LFS migrate -c2 $dom ||
18777                 error "failed to migrate to the new composite layout"
18778         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18779                 error "MDT stripe was not removed"
18780
18781         cancel_lru_locks mdc
18782         local new_md5=$(md5sum $dom)
18783         [ "$old_md5" == "$new_md5" ] ||
18784                 error "$old_md5 != $new_md5"
18785
18786         # Skip free space checks with ZFS
18787         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18788                 local mdtfree2=$(do_facet $facet \
18789                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18790                 [ $mdtfree2 -gt $mdtfree1 ] ||
18791                         error "MDT space is not freed after migration"
18792         fi
18793         return 0
18794 }
18795 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18796
18797 test_272c() {
18798         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18799                 skip "Need MDS version at least 2.11.50"
18800
18801         local dom=$DIR/$tdir/$tfile
18802         mkdir -p $DIR/$tdir
18803         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18804
18805         local mdtidx=$($LFS getstripe -m $dom)
18806         local mdtname=MDT$(printf %04x $mdtidx)
18807         local facet=mds$((mdtidx + 1))
18808
18809         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18810                 error "failed to write data into $dom"
18811         local old_md5=$(md5sum $dom)
18812         cancel_lru_locks mdc
18813         local mdtfree1=$(do_facet $facet \
18814                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18815
18816         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18817                 error "failed to migrate to the new composite layout"
18818         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18819                 error "MDT stripe was not removed"
18820
18821         cancel_lru_locks mdc
18822         local new_md5=$(md5sum $dom)
18823         [ "$old_md5" == "$new_md5" ] ||
18824                 error "$old_md5 != $new_md5"
18825
18826         # Skip free space checks with ZFS
18827         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18828                 local mdtfree2=$(do_facet $facet \
18829                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18830                 [ $mdtfree2 -gt $mdtfree1 ] ||
18831                         error "MDS space is not freed after migration"
18832         fi
18833         return 0
18834 }
18835 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18836
18837 test_272d() {
18838         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18839                 skip "Need MDS version at least 2.12.55"
18840
18841         local dom=$DIR/$tdir/$tfile
18842         mkdir -p $DIR/$tdir
18843         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18844
18845         local mdtidx=$($LFS getstripe -m $dom)
18846         local mdtname=MDT$(printf %04x $mdtidx)
18847         local facet=mds$((mdtidx + 1))
18848
18849         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18850                 error "failed to write data into $dom"
18851         local old_md5=$(md5sum $dom)
18852         cancel_lru_locks mdc
18853         local mdtfree1=$(do_facet $facet \
18854                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18855
18856         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
18857                 error "failed mirroring to the new composite layout"
18858         $LFS mirror resync $dom ||
18859                 error "failed mirror resync"
18860         $LFS mirror split --mirror-id 1 -d $dom ||
18861                 error "failed mirror split"
18862
18863         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18864                 error "MDT stripe was not removed"
18865
18866         cancel_lru_locks mdc
18867         local new_md5=$(md5sum $dom)
18868         [ "$old_md5" == "$new_md5" ] ||
18869                 error "$old_md5 != $new_md5"
18870
18871         # Skip free space checks with ZFS
18872         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18873                 local mdtfree2=$(do_facet $facet \
18874                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18875                 [ $mdtfree2 -gt $mdtfree1 ] ||
18876                         error "MDS space is not freed after DOM mirror deletion"
18877         fi
18878         return 0
18879 }
18880 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
18881
18882 test_272e() {
18883         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18884                 skip "Need MDS version at least 2.12.55"
18885
18886         local dom=$DIR/$tdir/$tfile
18887         mkdir -p $DIR/$tdir
18888         $LFS setstripe -c 2 $dom
18889
18890         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
18891                 error "failed to write data into $dom"
18892         local old_md5=$(md5sum $dom)
18893         cancel_lru_locks mdc
18894
18895         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
18896                 error "failed mirroring to the DOM layout"
18897         $LFS mirror resync $dom ||
18898                 error "failed mirror resync"
18899         $LFS mirror split --mirror-id 1 -d $dom ||
18900                 error "failed mirror split"
18901
18902         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18903                 error "MDT stripe was not removed"
18904
18905         cancel_lru_locks mdc
18906         local new_md5=$(md5sum $dom)
18907         [ "$old_md5" == "$new_md5" ] ||
18908                 error "$old_md5 != $new_md5"
18909
18910         return 0
18911 }
18912 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
18913
18914 test_272f() {
18915         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18916                 skip "Need MDS version at least 2.12.55"
18917
18918         local dom=$DIR/$tdir/$tfile
18919         mkdir -p $DIR/$tdir
18920         $LFS setstripe -c 2 $dom
18921
18922         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
18923                 error "failed to write data into $dom"
18924         local old_md5=$(md5sum $dom)
18925         cancel_lru_locks mdc
18926
18927         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
18928                 error "failed migrating to the DOM file"
18929
18930         cancel_lru_locks mdc
18931         local new_md5=$(md5sum $dom)
18932         [ "$old_md5" != "$new_md5" ] &&
18933                 error "$old_md5 != $new_md5"
18934
18935         return 0
18936 }
18937 run_test 272f "DoM migration: OST-striped file to DOM file"
18938
18939 test_273a() {
18940         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18941                 skip "Need MDS version at least 2.11.50"
18942
18943         # Layout swap cannot be done if either file has DOM component,
18944         # this will never be supported, migration should be used instead
18945
18946         local dom=$DIR/$tdir/$tfile
18947         mkdir -p $DIR/$tdir
18948
18949         $LFS setstripe -c2 ${dom}_plain
18950         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
18951         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
18952                 error "can swap layout with DoM component"
18953         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
18954                 error "can swap layout with DoM component"
18955
18956         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
18957         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
18958                 error "can swap layout with DoM component"
18959         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
18960                 error "can swap layout with DoM component"
18961         return 0
18962 }
18963 run_test 273a "DoM: layout swapping should fail with DOM"
18964
18965 test_275() {
18966         remote_ost_nodsh && skip "remote OST with nodsh"
18967         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
18968                 skip "Need OST version >= 2.10.57"
18969
18970         local file=$DIR/$tfile
18971         local oss
18972
18973         oss=$(comma_list $(osts_nodes))
18974
18975         dd if=/dev/urandom of=$file bs=1M count=2 ||
18976                 error "failed to create a file"
18977         cancel_lru_locks osc
18978
18979         #lock 1
18980         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18981                 error "failed to read a file"
18982
18983 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
18984         $LCTL set_param fail_loc=0x8000031f
18985
18986         cancel_lru_locks osc &
18987         sleep 1
18988
18989 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
18990         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
18991         #IO takes another lock, but matches the PENDING one
18992         #and places it to the IO RPC
18993         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18994                 error "failed to read a file with PENDING lock"
18995 }
18996 run_test 275 "Read on a canceled duplicate lock"
18997
18998 test_276() {
18999         remote_ost_nodsh && skip "remote OST with nodsh"
19000         local pid
19001
19002         do_facet ost1 "(while true; do \
19003                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
19004                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
19005         pid=$!
19006
19007         for LOOP in $(seq 20); do
19008                 stop ost1
19009                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
19010         done
19011         kill -9 $pid
19012         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
19013                 rm $TMP/sanity_276_pid"
19014 }
19015 run_test 276 "Race between mount and obd_statfs"
19016
19017 test_277() {
19018         $LCTL set_param ldlm.namespaces.*.lru_size=0
19019         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
19020         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19021                         grep ^used_mb | awk '{print $2}')
19022         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
19023         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
19024                 oflag=direct conv=notrunc
19025         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19026                         grep ^used_mb | awk '{print $2}')
19027         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
19028 }
19029 run_test 277 "Direct IO shall drop page cache"
19030
19031 test_278() {
19032         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19033         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19034         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
19035                 skip "needs the same host for mdt1 mdt2" && return
19036
19037         local pid1
19038         local pid2
19039
19040 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
19041         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
19042         stop mds2 &
19043         pid2=$!
19044
19045         stop mds1
19046
19047         echo "Starting MDTs"
19048         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
19049         wait $pid2
19050 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
19051 #will return NULL
19052         do_facet mds2 $LCTL set_param fail_loc=0
19053
19054         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
19055         wait_recovery_complete mds2
19056 }
19057 run_test 278 "Race starting MDS between MDTs stop/start"
19058
19059 cleanup_test_300() {
19060         trap 0
19061         umask $SAVE_UMASK
19062 }
19063 test_striped_dir() {
19064         local mdt_index=$1
19065         local stripe_count
19066         local stripe_index
19067
19068         mkdir -p $DIR/$tdir
19069
19070         SAVE_UMASK=$(umask)
19071         trap cleanup_test_300 RETURN EXIT
19072
19073         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
19074                                                 $DIR/$tdir/striped_dir ||
19075                 error "set striped dir error"
19076
19077         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
19078         [ "$mode" = "755" ] || error "expect 755 got $mode"
19079
19080         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
19081                 error "getdirstripe failed"
19082         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
19083         if [ "$stripe_count" != "2" ]; then
19084                 error "1:stripe_count is $stripe_count, expect 2"
19085         fi
19086         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
19087         if [ "$stripe_count" != "2" ]; then
19088                 error "2:stripe_count is $stripe_count, expect 2"
19089         fi
19090
19091         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
19092         if [ "$stripe_index" != "$mdt_index" ]; then
19093                 error "stripe_index is $stripe_index, expect $mdt_index"
19094         fi
19095
19096         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19097                 error "nlink error after create striped dir"
19098
19099         mkdir $DIR/$tdir/striped_dir/a
19100         mkdir $DIR/$tdir/striped_dir/b
19101
19102         stat $DIR/$tdir/striped_dir/a ||
19103                 error "create dir under striped dir failed"
19104         stat $DIR/$tdir/striped_dir/b ||
19105                 error "create dir under striped dir failed"
19106
19107         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
19108                 error "nlink error after mkdir"
19109
19110         rmdir $DIR/$tdir/striped_dir/a
19111         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
19112                 error "nlink error after rmdir"
19113
19114         rmdir $DIR/$tdir/striped_dir/b
19115         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19116                 error "nlink error after rmdir"
19117
19118         chattr +i $DIR/$tdir/striped_dir
19119         createmany -o $DIR/$tdir/striped_dir/f 10 &&
19120                 error "immutable flags not working under striped dir!"
19121         chattr -i $DIR/$tdir/striped_dir
19122
19123         rmdir $DIR/$tdir/striped_dir ||
19124                 error "rmdir striped dir error"
19125
19126         cleanup_test_300
19127
19128         true
19129 }
19130
19131 test_300a() {
19132         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19133                 skip "skipped for lustre < 2.7.0"
19134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19135         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19136
19137         test_striped_dir 0 || error "failed on striped dir on MDT0"
19138         test_striped_dir 1 || error "failed on striped dir on MDT0"
19139 }
19140 run_test 300a "basic striped dir sanity test"
19141
19142 test_300b() {
19143         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19144                 skip "skipped for lustre < 2.7.0"
19145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19146         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19147
19148         local i
19149         local mtime1
19150         local mtime2
19151         local mtime3
19152
19153         test_mkdir $DIR/$tdir || error "mkdir fail"
19154         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19155                 error "set striped dir error"
19156         for i in {0..9}; do
19157                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
19158                 sleep 1
19159                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
19160                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
19161                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
19162                 sleep 1
19163                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
19164                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
19165                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
19166         done
19167         true
19168 }
19169 run_test 300b "check ctime/mtime for striped dir"
19170
19171 test_300c() {
19172         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19173                 skip "skipped for lustre < 2.7.0"
19174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19175         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19176
19177         local file_count
19178
19179         mkdir -p $DIR/$tdir
19180         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
19181                 error "set striped dir error"
19182
19183         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
19184                 error "chown striped dir failed"
19185
19186         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
19187                 error "create 5k files failed"
19188
19189         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
19190
19191         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
19192
19193         rm -rf $DIR/$tdir
19194 }
19195 run_test 300c "chown && check ls under striped directory"
19196
19197 test_300d() {
19198         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19199                 skip "skipped for lustre < 2.7.0"
19200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19201         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19202
19203         local stripe_count
19204         local file
19205
19206         mkdir -p $DIR/$tdir
19207         $LFS setstripe -c 2 $DIR/$tdir
19208
19209         #local striped directory
19210         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19211                 error "set striped dir error"
19212         createmany -o $DIR/$tdir/striped_dir/f 10 ||
19213                 error "create 10 files failed"
19214
19215         #remote striped directory
19216         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
19217                 error "set striped dir error"
19218         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
19219                 error "create 10 files failed"
19220
19221         for file in $(find $DIR/$tdir); do
19222                 stripe_count=$($LFS getstripe -c $file)
19223                 [ $stripe_count -eq 2 ] ||
19224                         error "wrong stripe $stripe_count for $file"
19225         done
19226
19227         rm -rf $DIR/$tdir
19228 }
19229 run_test 300d "check default stripe under striped directory"
19230
19231 test_300e() {
19232         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19233                 skip "Need MDS version at least 2.7.55"
19234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19235         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19236
19237         local stripe_count
19238         local file
19239
19240         mkdir -p $DIR/$tdir
19241
19242         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19243                 error "set striped dir error"
19244
19245         touch $DIR/$tdir/striped_dir/a
19246         touch $DIR/$tdir/striped_dir/b
19247         touch $DIR/$tdir/striped_dir/c
19248
19249         mkdir $DIR/$tdir/striped_dir/dir_a
19250         mkdir $DIR/$tdir/striped_dir/dir_b
19251         mkdir $DIR/$tdir/striped_dir/dir_c
19252
19253         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
19254                 error "set striped adir under striped dir error"
19255
19256         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
19257                 error "set striped bdir under striped dir error"
19258
19259         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
19260                 error "set striped cdir under striped dir error"
19261
19262         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
19263                 error "rename dir under striped dir fails"
19264
19265         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
19266                 error "rename dir under different stripes fails"
19267
19268         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
19269                 error "rename file under striped dir should succeed"
19270
19271         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
19272                 error "rename dir under striped dir should succeed"
19273
19274         rm -rf $DIR/$tdir
19275 }
19276 run_test 300e "check rename under striped directory"
19277
19278 test_300f() {
19279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19280         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19281         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19282                 skip "Need MDS version at least 2.7.55"
19283
19284         local stripe_count
19285         local file
19286
19287         rm -rf $DIR/$tdir
19288         mkdir -p $DIR/$tdir
19289
19290         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19291                 error "set striped dir error"
19292
19293         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
19294                 error "set striped dir error"
19295
19296         touch $DIR/$tdir/striped_dir/a
19297         mkdir $DIR/$tdir/striped_dir/dir_a
19298         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
19299                 error "create striped dir under striped dir fails"
19300
19301         touch $DIR/$tdir/striped_dir1/b
19302         mkdir $DIR/$tdir/striped_dir1/dir_b
19303         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
19304                 error "create striped dir under striped dir fails"
19305
19306         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
19307                 error "rename dir under different striped dir should fail"
19308
19309         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
19310                 error "rename striped dir under diff striped dir should fail"
19311
19312         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
19313                 error "rename file under diff striped dirs fails"
19314
19315         rm -rf $DIR/$tdir
19316 }
19317 run_test 300f "check rename cross striped directory"
19318
19319 test_300_check_default_striped_dir()
19320 {
19321         local dirname=$1
19322         local default_count=$2
19323         local default_index=$3
19324         local stripe_count
19325         local stripe_index
19326         local dir_stripe_index
19327         local dir
19328
19329         echo "checking $dirname $default_count $default_index"
19330         $LFS setdirstripe -D -c $default_count -i $default_index \
19331                                 -t all_char $DIR/$tdir/$dirname ||
19332                 error "set default stripe on striped dir error"
19333         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
19334         [ $stripe_count -eq $default_count ] ||
19335                 error "expect $default_count get $stripe_count for $dirname"
19336
19337         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
19338         [ $stripe_index -eq $default_index ] ||
19339                 error "expect $default_index get $stripe_index for $dirname"
19340
19341         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
19342                                                 error "create dirs failed"
19343
19344         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
19345         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
19346         for dir in $(find $DIR/$tdir/$dirname/*); do
19347                 stripe_count=$($LFS getdirstripe -c $dir)
19348                 [ $stripe_count -eq $default_count ] ||
19349                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
19350                 error "stripe count $default_count != $stripe_count for $dir"
19351
19352                 stripe_index=$($LFS getdirstripe -i $dir)
19353                 [ $default_index -eq -1 ] ||
19354                         [ $stripe_index -eq $default_index ] ||
19355                         error "$stripe_index != $default_index for $dir"
19356
19357                 #check default stripe
19358                 stripe_count=$($LFS getdirstripe -D -c $dir)
19359                 [ $stripe_count -eq $default_count ] ||
19360                 error "default count $default_count != $stripe_count for $dir"
19361
19362                 stripe_index=$($LFS getdirstripe -D -i $dir)
19363                 [ $stripe_index -eq $default_index ] ||
19364                 error "default index $default_index != $stripe_index for $dir"
19365         done
19366         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
19367 }
19368
19369 test_300g() {
19370         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19371         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19372                 skip "Need MDS version at least 2.7.55"
19373
19374         local dir
19375         local stripe_count
19376         local stripe_index
19377
19378         mkdir $DIR/$tdir
19379         mkdir $DIR/$tdir/normal_dir
19380
19381         #Checking when client cache stripe index
19382         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
19383         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
19384                 error "create striped_dir failed"
19385
19386         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
19387                 error "create dir0 fails"
19388         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
19389         [ $stripe_index -eq 0 ] ||
19390                 error "dir0 expect index 0 got $stripe_index"
19391
19392         mkdir $DIR/$tdir/striped_dir/dir1 ||
19393                 error "create dir1 fails"
19394         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
19395         [ $stripe_index -eq 1 ] ||
19396                 error "dir1 expect index 1 got $stripe_index"
19397
19398         #check default stripe count/stripe index
19399         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
19400         test_300_check_default_striped_dir normal_dir 1 0
19401         test_300_check_default_striped_dir normal_dir 2 1
19402         test_300_check_default_striped_dir normal_dir 2 -1
19403
19404         #delete default stripe information
19405         echo "delete default stripeEA"
19406         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
19407                 error "set default stripe on striped dir error"
19408
19409         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
19410         for dir in $(find $DIR/$tdir/normal_dir/*); do
19411                 stripe_count=$($LFS getdirstripe -c $dir)
19412                 [ $stripe_count -eq 0 ] ||
19413                         error "expect 1 get $stripe_count for $dir"
19414                 stripe_index=$($LFS getdirstripe -i $dir)
19415                 [ $stripe_index -eq 0 ] ||
19416                         error "expect 0 get $stripe_index for $dir"
19417         done
19418 }
19419 run_test 300g "check default striped directory for normal directory"
19420
19421 test_300h() {
19422         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19423         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19424                 skip "Need MDS version at least 2.7.55"
19425
19426         local dir
19427         local stripe_count
19428
19429         mkdir $DIR/$tdir
19430         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19431                 error "set striped dir error"
19432
19433         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
19434         test_300_check_default_striped_dir striped_dir 1 0
19435         test_300_check_default_striped_dir striped_dir 2 1
19436         test_300_check_default_striped_dir striped_dir 2 -1
19437
19438         #delete default stripe information
19439         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
19440                 error "set default stripe on striped dir error"
19441
19442         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
19443         for dir in $(find $DIR/$tdir/striped_dir/*); do
19444                 stripe_count=$($LFS getdirstripe -c $dir)
19445                 [ $stripe_count -eq 0 ] ||
19446                         error "expect 1 get $stripe_count for $dir"
19447         done
19448 }
19449 run_test 300h "check default striped directory for striped directory"
19450
19451 test_300i() {
19452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19453         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19454         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19455                 skip "Need MDS version at least 2.7.55"
19456
19457         local stripe_count
19458         local file
19459
19460         mkdir $DIR/$tdir
19461
19462         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19463                 error "set striped dir error"
19464
19465         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19466                 error "create files under striped dir failed"
19467
19468         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
19469                 error "set striped hashdir error"
19470
19471         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
19472                 error "create dir0 under hash dir failed"
19473         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
19474                 error "create dir1 under hash dir failed"
19475
19476         # unfortunately, we need to umount to clear dir layout cache for now
19477         # once we fully implement dir layout, we can drop this
19478         umount_client $MOUNT || error "umount failed"
19479         mount_client $MOUNT || error "mount failed"
19480
19481         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
19482         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
19483         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
19484
19485         #set the stripe to be unknown hash type
19486         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
19487         $LCTL set_param fail_loc=0x1901
19488         for ((i = 0; i < 10; i++)); do
19489                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
19490                         error "stat f-$i failed"
19491                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
19492         done
19493
19494         touch $DIR/$tdir/striped_dir/f0 &&
19495                 error "create under striped dir with unknown hash should fail"
19496
19497         $LCTL set_param fail_loc=0
19498
19499         umount_client $MOUNT || error "umount failed"
19500         mount_client $MOUNT || error "mount failed"
19501
19502         return 0
19503 }
19504 run_test 300i "client handle unknown hash type striped directory"
19505
19506 test_300j() {
19507         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19509         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19510                 skip "Need MDS version at least 2.7.55"
19511
19512         local stripe_count
19513         local file
19514
19515         mkdir $DIR/$tdir
19516
19517         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
19518         $LCTL set_param fail_loc=0x1702
19519         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19520                 error "set striped dir error"
19521
19522         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19523                 error "create files under striped dir failed"
19524
19525         $LCTL set_param fail_loc=0
19526
19527         rm -rf $DIR/$tdir || error "unlink striped dir fails"
19528
19529         return 0
19530 }
19531 run_test 300j "test large update record"
19532
19533 test_300k() {
19534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19535         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19536         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19537                 skip "Need MDS version at least 2.7.55"
19538
19539         # this test needs a huge transaction
19540         local kb
19541         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
19542         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
19543
19544         local stripe_count
19545         local file
19546
19547         mkdir $DIR/$tdir
19548
19549         #define OBD_FAIL_LARGE_STRIPE   0x1703
19550         $LCTL set_param fail_loc=0x1703
19551         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
19552                 error "set striped dir error"
19553         $LCTL set_param fail_loc=0
19554
19555         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19556                 error "getstripeddir fails"
19557         rm -rf $DIR/$tdir/striped_dir ||
19558                 error "unlink striped dir fails"
19559
19560         return 0
19561 }
19562 run_test 300k "test large striped directory"
19563
19564 test_300l() {
19565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19566         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19567         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19568                 skip "Need MDS version at least 2.7.55"
19569
19570         local stripe_index
19571
19572         test_mkdir -p $DIR/$tdir/striped_dir
19573         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
19574                         error "chown $RUNAS_ID failed"
19575         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
19576                 error "set default striped dir failed"
19577
19578         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
19579         $LCTL set_param fail_loc=0x80000158
19580         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
19581
19582         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
19583         [ $stripe_index -eq 1 ] ||
19584                 error "expect 1 get $stripe_index for $dir"
19585 }
19586 run_test 300l "non-root user to create dir under striped dir with stale layout"
19587
19588 test_300m() {
19589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19590         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
19591         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19592                 skip "Need MDS version at least 2.7.55"
19593
19594         mkdir -p $DIR/$tdir/striped_dir
19595         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
19596                 error "set default stripes dir error"
19597
19598         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
19599
19600         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
19601         [ $stripe_count -eq 0 ] ||
19602                         error "expect 0 get $stripe_count for a"
19603
19604         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
19605                 error "set default stripes dir error"
19606
19607         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
19608
19609         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
19610         [ $stripe_count -eq 0 ] ||
19611                         error "expect 0 get $stripe_count for b"
19612
19613         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
19614                 error "set default stripes dir error"
19615
19616         mkdir $DIR/$tdir/striped_dir/c &&
19617                 error "default stripe_index is invalid, mkdir c should fails"
19618
19619         rm -rf $DIR/$tdir || error "rmdir fails"
19620 }
19621 run_test 300m "setstriped directory on single MDT FS"
19622
19623 cleanup_300n() {
19624         local list=$(comma_list $(mdts_nodes))
19625
19626         trap 0
19627         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19628 }
19629
19630 test_300n() {
19631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19632         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19633         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19634                 skip "Need MDS version at least 2.7.55"
19635         remote_mds_nodsh && skip "remote MDS with nodsh"
19636
19637         local stripe_index
19638         local list=$(comma_list $(mdts_nodes))
19639
19640         trap cleanup_300n RETURN EXIT
19641         mkdir -p $DIR/$tdir
19642         chmod 777 $DIR/$tdir
19643         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
19644                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19645                 error "create striped dir succeeds with gid=0"
19646
19647         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19648         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
19649                 error "create striped dir fails with gid=-1"
19650
19651         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19652         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
19653                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19654                 error "set default striped dir succeeds with gid=0"
19655
19656
19657         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19658         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
19659                 error "set default striped dir fails with gid=-1"
19660
19661
19662         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19663         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
19664                                         error "create test_dir fails"
19665         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
19666                                         error "create test_dir1 fails"
19667         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
19668                                         error "create test_dir2 fails"
19669         cleanup_300n
19670 }
19671 run_test 300n "non-root user to create dir under striped dir with default EA"
19672
19673 test_300o() {
19674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19675         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19676         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19677                 skip "Need MDS version at least 2.7.55"
19678
19679         local numfree1
19680         local numfree2
19681
19682         mkdir -p $DIR/$tdir
19683
19684         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
19685         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
19686         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
19687                 skip "not enough free inodes $numfree1 $numfree2"
19688         fi
19689
19690         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
19691         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
19692         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
19693                 skip "not enough free space $numfree1 $numfree2"
19694         fi
19695
19696         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
19697                 error "setdirstripe fails"
19698
19699         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
19700                 error "create dirs fails"
19701
19702         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
19703         ls $DIR/$tdir/striped_dir > /dev/null ||
19704                 error "ls striped dir fails"
19705         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
19706                 error "unlink big striped dir fails"
19707 }
19708 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
19709
19710 test_300p() {
19711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19712         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19713         remote_mds_nodsh && skip "remote MDS with nodsh"
19714
19715         mkdir -p $DIR/$tdir
19716
19717         #define OBD_FAIL_OUT_ENOSPC     0x1704
19718         do_facet mds2 lctl set_param fail_loc=0x80001704
19719         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
19720                  && error "create striped directory should fail"
19721
19722         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
19723
19724         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
19725         true
19726 }
19727 run_test 300p "create striped directory without space"
19728
19729 test_300q() {
19730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19731         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19732
19733         local fd=$(free_fd)
19734         local cmd="exec $fd<$tdir"
19735         cd $DIR
19736         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
19737         eval $cmd
19738         cmd="exec $fd<&-"
19739         trap "eval $cmd" EXIT
19740         cd $tdir || error "cd $tdir fails"
19741         rmdir  ../$tdir || error "rmdir $tdir fails"
19742         mkdir local_dir && error "create dir succeeds"
19743         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
19744         eval $cmd
19745         return 0
19746 }
19747 run_test 300q "create remote directory under orphan directory"
19748
19749 test_300r() {
19750         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
19751                 skip "Need MDS version at least 2.7.55" && return
19752         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19753
19754         mkdir $DIR/$tdir
19755
19756         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19757                 error "set striped dir error"
19758
19759         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19760                 error "getstripeddir fails"
19761
19762         local stripe_count
19763         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19764                       awk '/lmv_stripe_count:/ { print $2 }')
19765
19766         [ $MDSCOUNT -ne $stripe_count ] &&
19767                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19768
19769         rm -rf $DIR/$tdir/striped_dir ||
19770                 error "unlink striped dir fails"
19771 }
19772 run_test 300r "test -1 striped directory"
19773
19774 prepare_remote_file() {
19775         mkdir $DIR/$tdir/src_dir ||
19776                 error "create remote source failed"
19777
19778         cp /etc/hosts $DIR/$tdir/src_dir/a ||
19779                  error "cp to remote source failed"
19780         touch $DIR/$tdir/src_dir/a
19781
19782         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
19783                 error "create remote target dir failed"
19784
19785         touch $DIR/$tdir/tgt_dir/b
19786
19787         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
19788                 error "rename dir cross MDT failed!"
19789
19790         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
19791                 error "src_child still exists after rename"
19792
19793         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
19794                 error "missing file(a) after rename"
19795
19796         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
19797                 error "diff after rename"
19798 }
19799
19800 test_310a() {
19801         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19803
19804         local remote_file=$DIR/$tdir/tgt_dir/b
19805
19806         mkdir -p $DIR/$tdir
19807
19808         prepare_remote_file || error "prepare remote file failed"
19809
19810         #open-unlink file
19811         $OPENUNLINK $remote_file $remote_file ||
19812                 error "openunlink $remote_file failed"
19813         $CHECKSTAT -a $remote_file || error "$remote_file exists"
19814 }
19815 run_test 310a "open unlink remote file"
19816
19817 test_310b() {
19818         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19820
19821         local remote_file=$DIR/$tdir/tgt_dir/b
19822
19823         mkdir -p $DIR/$tdir
19824
19825         prepare_remote_file || error "prepare remote file failed"
19826
19827         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19828         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19829         $CHECKSTAT -t file $remote_file || error "check file failed"
19830 }
19831 run_test 310b "unlink remote file with multiple links while open"
19832
19833 test_310c() {
19834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19835         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19836
19837         local remote_file=$DIR/$tdir/tgt_dir/b
19838
19839         mkdir -p $DIR/$tdir
19840
19841         prepare_remote_file || error "prepare remote file failed"
19842
19843         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19844         multiop_bg_pause $remote_file O_uc ||
19845                         error "mulitop failed for remote file"
19846         MULTIPID=$!
19847         $MULTIOP $DIR/$tfile Ouc
19848         kill -USR1 $MULTIPID
19849         wait $MULTIPID
19850 }
19851 run_test 310c "open-unlink remote file with multiple links"
19852
19853 #LU-4825
19854 test_311() {
19855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19856         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19857         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
19858                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
19859         remote_mds_nodsh && skip "remote MDS with nodsh"
19860
19861         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19862         local mdts=$(comma_list $(mdts_nodes))
19863
19864         mkdir -p $DIR/$tdir
19865         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19866         createmany -o $DIR/$tdir/$tfile. 1000
19867
19868         # statfs data is not real time, let's just calculate it
19869         old_iused=$((old_iused + 1000))
19870
19871         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19872                         osp.*OST0000*MDT0000.create_count")
19873         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19874                                 osp.*OST0000*MDT0000.max_create_count")
19875         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
19876
19877         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
19878         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
19879         [ $index -ne 0 ] || error "$tfile stripe index is 0"
19880
19881         unlinkmany $DIR/$tdir/$tfile. 1000
19882
19883         do_nodes $mdts "$LCTL set_param -n \
19884                         osp.*OST0000*.max_create_count=$max_count"
19885         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
19886                 do_nodes $mdts "$LCTL set_param -n \
19887                                 osp.*OST0000*.create_count=$count"
19888         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
19889                         grep "=0" && error "create_count is zero"
19890
19891         local new_iused
19892         for i in $(seq 120); do
19893                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19894                 # system may be too busy to destroy all objs in time, use
19895                 # a somewhat small value to not fail autotest
19896                 [ $((old_iused - new_iused)) -gt 400 ] && break
19897                 sleep 1
19898         done
19899
19900         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
19901         [ $((old_iused - new_iused)) -gt 400 ] ||
19902                 error "objs not destroyed after unlink"
19903 }
19904 run_test 311 "disable OSP precreate, and unlink should destroy objs"
19905
19906 zfs_oid_to_objid()
19907 {
19908         local ost=$1
19909         local objid=$2
19910
19911         local vdevdir=$(dirname $(facet_vdevice $ost))
19912         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
19913         local zfs_zapid=$(do_facet $ost $cmd |
19914                           grep -w "/O/0/d$((objid%32))" -C 5 |
19915                           awk '/Object/{getline; print $1}')
19916         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
19917                           awk "/$objid = /"'{printf $3}')
19918
19919         echo $zfs_objid
19920 }
19921
19922 zfs_object_blksz() {
19923         local ost=$1
19924         local objid=$2
19925
19926         local vdevdir=$(dirname $(facet_vdevice $ost))
19927         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
19928         local blksz=$(do_facet $ost $cmd $objid |
19929                       awk '/dblk/{getline; printf $4}')
19930
19931         case "${blksz: -1}" in
19932                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
19933                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
19934                 *) ;;
19935         esac
19936
19937         echo $blksz
19938 }
19939
19940 test_312() { # LU-4856
19941         remote_ost_nodsh && skip "remote OST with nodsh"
19942         [ "$ost1_FSTYPE" = "zfs" ] ||
19943                 skip_env "the test only applies to zfs"
19944
19945         local max_blksz=$(do_facet ost1 \
19946                           $ZFS get -p recordsize $(facet_device ost1) |
19947                           awk '!/VALUE/{print $3}')
19948
19949         # to make life a little bit easier
19950         $LFS mkdir -c 1 -i 0 $DIR/$tdir
19951         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19952
19953         local tf=$DIR/$tdir/$tfile
19954         touch $tf
19955         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19956
19957         # Get ZFS object id
19958         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19959         # block size change by sequential overwrite
19960         local bs
19961
19962         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
19963                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
19964
19965                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
19966                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
19967         done
19968         rm -f $tf
19969
19970         # block size change by sequential append write
19971         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
19972         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19973         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19974         local count
19975
19976         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
19977                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
19978                         oflag=sync conv=notrunc
19979
19980                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
19981                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
19982                         error "blksz error, actual $blksz, " \
19983                                 "expected: 2 * $count * $PAGE_SIZE"
19984         done
19985         rm -f $tf
19986
19987         # random write
19988         touch $tf
19989         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19990         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19991
19992         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
19993         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19994         [ $blksz -eq $PAGE_SIZE ] ||
19995                 error "blksz error: $blksz, expected: $PAGE_SIZE"
19996
19997         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
19998         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19999         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
20000
20001         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
20002         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20003         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
20004 }
20005 run_test 312 "make sure ZFS adjusts its block size by write pattern"
20006
20007 test_313() {
20008         remote_ost_nodsh && skip "remote OST with nodsh"
20009
20010         local file=$DIR/$tfile
20011
20012         rm -f $file
20013         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
20014
20015         # define OBD_FAIL_TGT_RCVD_EIO           0x720
20016         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20017         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
20018                 error "write should failed"
20019         do_facet ost1 "$LCTL set_param fail_loc=0"
20020         rm -f $file
20021 }
20022 run_test 313 "io should fail after last_rcvd update fail"
20023
20024 test_314() {
20025         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20026
20027         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
20028         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20029         rm -f $DIR/$tfile
20030         wait_delete_completed
20031         do_facet ost1 "$LCTL set_param fail_loc=0"
20032 }
20033 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
20034
20035 test_315() { # LU-618
20036         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
20037
20038         local file=$DIR/$tfile
20039         rm -f $file
20040
20041         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
20042                 error "multiop file write failed"
20043         $MULTIOP $file oO_RDONLY:r4063232_c &
20044         PID=$!
20045
20046         sleep 2
20047
20048         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
20049         kill -USR1 $PID
20050
20051         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
20052         rm -f $file
20053 }
20054 run_test 315 "read should be accounted"
20055
20056 test_316() {
20057         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20058         large_xattr_enabled || skip_env "ea_inode feature disabled"
20059
20060         rm -rf $DIR/$tdir/d
20061         mkdir -p $DIR/$tdir/d
20062         chown nobody $DIR/$tdir/d
20063         touch $DIR/$tdir/d/file
20064
20065         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
20066 }
20067 run_test 316 "lfs mv"
20068
20069 test_317() {
20070         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
20071                 skip "Need MDS version at least 2.11.53"
20072         if [ "$ost1_FSTYPE" == "zfs" ]; then
20073                 skip "LU-10370: no implementation for ZFS"
20074         fi
20075
20076         local trunc_sz
20077         local grant_blk_size
20078
20079         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
20080                         awk '/grant_block_size:/ { print $2; exit; }')
20081         #
20082         # Create File of size 5M. Truncate it to below size's and verify
20083         # blocks count.
20084         #
20085         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
20086                 error "Create file $DIR/$tfile failed"
20087         stack_trap "rm -f $DIR/$tfile" EXIT
20088
20089         for trunc_sz in 2097152 4097 4000 509 0; do
20090                 $TRUNCATE $DIR/$tfile $trunc_sz ||
20091                         error "truncate $tfile to $trunc_sz failed"
20092                 local sz=$(stat --format=%s $DIR/$tfile)
20093                 local blk=$(stat --format=%b $DIR/$tfile)
20094                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
20095                                      grant_blk_size) * 8))
20096
20097                 if [[ $blk -ne $trunc_blk ]]; then
20098                         $(which stat) $DIR/$tfile
20099                         error "Expected Block $trunc_blk got $blk for $tfile"
20100                 fi
20101
20102                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20103                         error "Expected Size $trunc_sz got $sz for $tfile"
20104         done
20105
20106         #
20107         # sparse file test
20108         # Create file with a hole and write actual two blocks. Block count
20109         # must be 16.
20110         #
20111         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
20112                 conv=fsync || error "Create file : $DIR/$tfile"
20113
20114         # Calculate the final truncate size.
20115         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
20116
20117         #
20118         # truncate to size $trunc_sz bytes. Strip the last block
20119         # The block count must drop to 8
20120         #
20121         $TRUNCATE $DIR/$tfile $trunc_sz ||
20122                 error "truncate $tfile to $trunc_sz failed"
20123
20124         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
20125         sz=$(stat --format=%s $DIR/$tfile)
20126         blk=$(stat --format=%b $DIR/$tfile)
20127
20128         if [[ $blk -ne $trunc_bsz ]]; then
20129                 $(which stat) $DIR/$tfile
20130                 error "Expected Block $trunc_bsz got $blk for $tfile"
20131         fi
20132
20133         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20134                 error "Expected Size $trunc_sz got $sz for $tfile"
20135 }
20136 run_test 317 "Verify blocks get correctly update after truncate"
20137
20138 test_318() {
20139         local old_max_active=$($LCTL get_param -n \
20140                             llite.*.max_read_ahead_async_active 2>/dev/null)
20141
20142         $LCTL set_param llite.*.max_read_ahead_async_active=256
20143         local max_active=$($LCTL get_param -n \
20144                            llite.*.max_read_ahead_async_active 2>/dev/null)
20145         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
20146
20147         # currently reset to 0 is unsupported, leave it 512 for now.
20148         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
20149                 error "set max_read_ahead_async_active should fail"
20150
20151         $LCTL set_param llite.*.max_read_ahead_async_active=512
20152         max_active=$($LCTL get_param -n \
20153                      llite.*.max_read_ahead_async_active 2>/dev/null)
20154         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
20155
20156         # restore @max_active
20157         [ $old_max_active -ne 0 ] && $LCTL set_param \
20158                 llite.*.max_read_ahead_async_active=$old_max_active
20159
20160         local old_threshold=$($LCTL get_param -n \
20161                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20162         local max_per_file_mb=$($LCTL get_param -n \
20163                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
20164
20165         local invalid=$(($max_per_file_mb + 1))
20166         $LCTL set_param \
20167                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
20168                         && error "set $invalid should fail"
20169
20170         local valid=$(($invalid - 1))
20171         $LCTL set_param \
20172                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
20173                         error "set $valid should succeed"
20174         local threshold=$($LCTL get_param -n \
20175                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20176         [ $threshold -eq $valid ] || error \
20177                 "expect threshold $valid got $threshold"
20178         $LCTL set_param \
20179                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
20180 }
20181 run_test 318 "Verify async readahead tunables"
20182
20183 test_319() {
20184         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
20185
20186         local before=$(date +%s)
20187         local evict
20188         local mdir=$DIR/$tdir
20189         local file=$mdir/xxx
20190
20191         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
20192         touch $file
20193
20194 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
20195         $LCTL set_param fail_val=5 fail_loc=0x8000032c
20196         $LFS mv -m1 $file &
20197
20198         sleep 1
20199         dd if=$file of=/dev/null
20200         wait
20201         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
20202           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
20203
20204         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
20205 }
20206 run_test 319 "lost lease lock on migrate error"
20207
20208 test_fake_rw() {
20209         local read_write=$1
20210         if [ "$read_write" = "write" ]; then
20211                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
20212         elif [ "$read_write" = "read" ]; then
20213                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
20214         else
20215                 error "argument error"
20216         fi
20217
20218         # turn off debug for performance testing
20219         local saved_debug=$($LCTL get_param -n debug)
20220         $LCTL set_param debug=0
20221
20222         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20223
20224         # get ost1 size - lustre-OST0000
20225         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
20226         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
20227         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
20228
20229         if [ "$read_write" = "read" ]; then
20230                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
20231         fi
20232
20233         local start_time=$(date +%s.%N)
20234         $dd_cmd bs=1M count=$blocks oflag=sync ||
20235                 error "real dd $read_write error"
20236         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
20237
20238         if [ "$read_write" = "write" ]; then
20239                 rm -f $DIR/$tfile
20240         fi
20241
20242         # define OBD_FAIL_OST_FAKE_RW           0x238
20243         do_facet ost1 $LCTL set_param fail_loc=0x238
20244
20245         local start_time=$(date +%s.%N)
20246         $dd_cmd bs=1M count=$blocks oflag=sync ||
20247                 error "fake dd $read_write error"
20248         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
20249
20250         if [ "$read_write" = "write" ]; then
20251                 # verify file size
20252                 cancel_lru_locks osc
20253                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
20254                         error "$tfile size not $blocks MB"
20255         fi
20256         do_facet ost1 $LCTL set_param fail_loc=0
20257
20258         echo "fake $read_write $duration_fake vs. normal $read_write" \
20259                 "$duration in seconds"
20260         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
20261                 error_not_in_vm "fake write is slower"
20262
20263         $LCTL set_param -n debug="$saved_debug"
20264         rm -f $DIR/$tfile
20265 }
20266 test_399a() { # LU-7655 for OST fake write
20267         remote_ost_nodsh && skip "remote OST with nodsh"
20268
20269         test_fake_rw write
20270 }
20271 run_test 399a "fake write should not be slower than normal write"
20272
20273 test_399b() { # LU-8726 for OST fake read
20274         remote_ost_nodsh && skip "remote OST with nodsh"
20275         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
20276                 skip_env "ldiskfs only test"
20277         fi
20278
20279         test_fake_rw read
20280 }
20281 run_test 399b "fake read should not be slower than normal read"
20282
20283 test_400a() { # LU-1606, was conf-sanity test_74
20284         if ! which $CC > /dev/null 2>&1; then
20285                 skip_env "$CC is not installed"
20286         fi
20287
20288         local extra_flags=''
20289         local out=$TMP/$tfile
20290         local prefix=/usr/include/lustre
20291         local prog
20292
20293         if ! [[ -d $prefix ]]; then
20294                 # Assume we're running in tree and fixup the include path.
20295                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
20296                 extra_flags+=" -L$LUSTRE/utils/.lib"
20297         fi
20298
20299         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
20300                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
20301                         error "client api broken"
20302         done
20303         rm -f $out
20304 }
20305 run_test 400a "Lustre client api program can compile and link"
20306
20307 test_400b() { # LU-1606, LU-5011
20308         local header
20309         local out=$TMP/$tfile
20310         local prefix=/usr/include/linux/lustre
20311
20312         # We use a hard coded prefix so that this test will not fail
20313         # when run in tree. There are headers in lustre/include/lustre/
20314         # that are not packaged (like lustre_idl.h) and have more
20315         # complicated include dependencies (like config.h and lnet/types.h).
20316         # Since this test about correct packaging we just skip them when
20317         # they don't exist (see below) rather than try to fixup cppflags.
20318
20319         if ! which $CC > /dev/null 2>&1; then
20320                 skip_env "$CC is not installed"
20321         fi
20322
20323         for header in $prefix/*.h; do
20324                 if ! [[ -f "$header" ]]; then
20325                         continue
20326                 fi
20327
20328                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
20329                         continue # lustre_ioctl.h is internal header
20330                 fi
20331
20332                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
20333                         error "cannot compile '$header'"
20334         done
20335         rm -f $out
20336 }
20337 run_test 400b "packaged headers can be compiled"
20338
20339 test_401a() { #LU-7437
20340         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
20341         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
20342
20343         #count the number of parameters by "list_param -R"
20344         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
20345         #count the number of parameters by listing proc files
20346         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
20347         echo "proc_dirs='$proc_dirs'"
20348         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
20349         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
20350                       sort -u | wc -l)
20351
20352         [ $params -eq $procs ] ||
20353                 error "found $params parameters vs. $procs proc files"
20354
20355         # test the list_param -D option only returns directories
20356         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
20357         #count the number of parameters by listing proc directories
20358         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
20359                 sort -u | wc -l)
20360
20361         [ $params -eq $procs ] ||
20362                 error "found $params parameters vs. $procs proc files"
20363 }
20364 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
20365
20366 test_401b() {
20367         local save=$($LCTL get_param -n jobid_var)
20368         local tmp=testing
20369
20370         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
20371                 error "no error returned when setting bad parameters"
20372
20373         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
20374         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
20375
20376         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
20377         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
20378         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
20379 }
20380 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
20381
20382 test_401c() {
20383         local jobid_var_old=$($LCTL get_param -n jobid_var)
20384         local jobid_var_new
20385
20386         $LCTL set_param jobid_var= &&
20387                 error "no error returned for 'set_param a='"
20388
20389         jobid_var_new=$($LCTL get_param -n jobid_var)
20390         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20391                 error "jobid_var was changed by setting without value"
20392
20393         $LCTL set_param jobid_var &&
20394                 error "no error returned for 'set_param a'"
20395
20396         jobid_var_new=$($LCTL get_param -n jobid_var)
20397         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20398                 error "jobid_var was changed by setting without value"
20399 }
20400 run_test 401c "Verify 'lctl set_param' without value fails in either format."
20401
20402 test_401d() {
20403         local jobid_var_old=$($LCTL get_param -n jobid_var)
20404         local jobid_var_new
20405         local new_value="foo=bar"
20406
20407         $LCTL set_param jobid_var=$new_value ||
20408                 error "'set_param a=b' did not accept a value containing '='"
20409
20410         jobid_var_new=$($LCTL get_param -n jobid_var)
20411         [[ "$jobid_var_new" == "$new_value" ]] ||
20412                 error "'set_param a=b' failed on a value containing '='"
20413
20414         # Reset the jobid_var to test the other format
20415         $LCTL set_param jobid_var=$jobid_var_old
20416         jobid_var_new=$($LCTL get_param -n jobid_var)
20417         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20418                 error "failed to reset jobid_var"
20419
20420         $LCTL set_param jobid_var $new_value ||
20421                 error "'set_param a b' did not accept a value containing '='"
20422
20423         jobid_var_new=$($LCTL get_param -n jobid_var)
20424         [[ "$jobid_var_new" == "$new_value" ]] ||
20425                 error "'set_param a b' failed on a value containing '='"
20426
20427         $LCTL set_param jobid_var $jobid_var_old
20428         jobid_var_new=$($LCTL get_param -n jobid_var)
20429         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20430                 error "failed to reset jobid_var"
20431 }
20432 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
20433
20434 test_402() {
20435         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
20436         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
20437                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
20438         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
20439                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
20440                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
20441         remote_mds_nodsh && skip "remote MDS with nodsh"
20442
20443         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
20444 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
20445         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
20446         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
20447                 echo "Touch failed - OK"
20448 }
20449 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
20450
20451 test_403() {
20452         local file1=$DIR/$tfile.1
20453         local file2=$DIR/$tfile.2
20454         local tfile=$TMP/$tfile
20455
20456         rm -f $file1 $file2 $tfile
20457
20458         touch $file1
20459         ln $file1 $file2
20460
20461         # 30 sec OBD_TIMEOUT in ll_getattr()
20462         # right before populating st_nlink
20463         $LCTL set_param fail_loc=0x80001409
20464         stat -c %h $file1 > $tfile &
20465
20466         # create an alias, drop all locks and reclaim the dentry
20467         < $file2
20468         cancel_lru_locks mdc
20469         cancel_lru_locks osc
20470         sysctl -w vm.drop_caches=2
20471
20472         wait
20473
20474         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
20475
20476         rm -f $tfile $file1 $file2
20477 }
20478 run_test 403 "i_nlink should not drop to zero due to aliasing"
20479
20480 test_404() { # LU-6601
20481         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
20482                 skip "Need server version newer than 2.8.52"
20483         remote_mds_nodsh && skip "remote MDS with nodsh"
20484
20485         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
20486                 awk '/osp .*-osc-MDT/ { print $4}')
20487
20488         local osp
20489         for osp in $mosps; do
20490                 echo "Deactivate: " $osp
20491                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
20492                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20493                         awk -vp=$osp '$4 == p { print $2 }')
20494                 [ $stat = IN ] || {
20495                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20496                         error "deactivate error"
20497                 }
20498                 echo "Activate: " $osp
20499                 do_facet $SINGLEMDS $LCTL --device %$osp activate
20500                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20501                         awk -vp=$osp '$4 == p { print $2 }')
20502                 [ $stat = UP ] || {
20503                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20504                         error "activate error"
20505                 }
20506         done
20507 }
20508 run_test 404 "validate manual {de}activated works properly for OSPs"
20509
20510 test_405() {
20511         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20512         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
20513                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
20514                         skip "Layout swap lock is not supported"
20515
20516         check_swap_layouts_support
20517
20518         test_mkdir $DIR/$tdir
20519         swap_lock_test -d $DIR/$tdir ||
20520                 error "One layout swap locked test failed"
20521 }
20522 run_test 405 "Various layout swap lock tests"
20523
20524 test_406() {
20525         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20526         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20527         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20529         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
20530                 skip "Need MDS version at least 2.8.50"
20531
20532         local def_stripe_size=$($LFS getstripe -S $MOUNT)
20533         local test_pool=$TESTNAME
20534
20535         pool_add $test_pool || error "pool_add failed"
20536         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
20537                 error "pool_add_targets failed"
20538
20539         save_layout_restore_at_exit $MOUNT
20540
20541         # parent set default stripe count only, child will stripe from both
20542         # parent and fs default
20543         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
20544                 error "setstripe $MOUNT failed"
20545         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
20546         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
20547         for i in $(seq 10); do
20548                 local f=$DIR/$tdir/$tfile.$i
20549                 touch $f || error "touch failed"
20550                 local count=$($LFS getstripe -c $f)
20551                 [ $count -eq $OSTCOUNT ] ||
20552                         error "$f stripe count $count != $OSTCOUNT"
20553                 local offset=$($LFS getstripe -i $f)
20554                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
20555                 local size=$($LFS getstripe -S $f)
20556                 [ $size -eq $((def_stripe_size * 2)) ] ||
20557                         error "$f stripe size $size != $((def_stripe_size * 2))"
20558                 local pool=$($LFS getstripe -p $f)
20559                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
20560         done
20561
20562         # change fs default striping, delete parent default striping, now child
20563         # will stripe from new fs default striping only
20564         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
20565                 error "change $MOUNT default stripe failed"
20566         $LFS setstripe -c 0 $DIR/$tdir ||
20567                 error "delete $tdir default stripe failed"
20568         for i in $(seq 11 20); do
20569                 local f=$DIR/$tdir/$tfile.$i
20570                 touch $f || error "touch $f failed"
20571                 local count=$($LFS getstripe -c $f)
20572                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
20573                 local offset=$($LFS getstripe -i $f)
20574                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
20575                 local size=$($LFS getstripe -S $f)
20576                 [ $size -eq $def_stripe_size ] ||
20577                         error "$f stripe size $size != $def_stripe_size"
20578                 local pool=$($LFS getstripe -p $f)
20579                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
20580         done
20581
20582         unlinkmany $DIR/$tdir/$tfile. 1 20
20583
20584         local f=$DIR/$tdir/$tfile
20585         pool_remove_all_targets $test_pool $f
20586         pool_remove $test_pool $f
20587 }
20588 run_test 406 "DNE support fs default striping"
20589
20590 test_407() {
20591         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20592         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20593                 skip "Need MDS version at least 2.8.55"
20594         remote_mds_nodsh && skip "remote MDS with nodsh"
20595
20596         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
20597                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
20598         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
20599                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
20600         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
20601
20602         #define OBD_FAIL_DT_TXN_STOP    0x2019
20603         for idx in $(seq $MDSCOUNT); do
20604                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
20605         done
20606         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
20607         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
20608                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
20609         true
20610 }
20611 run_test 407 "transaction fail should cause operation fail"
20612
20613 test_408() {
20614         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20615
20616         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
20617         lctl set_param fail_loc=0x8000040a
20618         # let ll_prepare_partial_page() fail
20619         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
20620
20621         rm -f $DIR/$tfile
20622
20623         # create at least 100 unused inodes so that
20624         # shrink_icache_memory(0) should not return 0
20625         touch $DIR/$tfile-{0..100}
20626         rm -f $DIR/$tfile-{0..100}
20627         sync
20628
20629         echo 2 > /proc/sys/vm/drop_caches
20630 }
20631 run_test 408 "drop_caches should not hang due to page leaks"
20632
20633 test_409()
20634 {
20635         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20636
20637         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
20638         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
20639         touch $DIR/$tdir/guard || error "(2) Fail to create"
20640
20641         local PREFIX=$(str_repeat 'A' 128)
20642         echo "Create 1K hard links start at $(date)"
20643         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20644                 error "(3) Fail to hard link"
20645
20646         echo "Links count should be right although linkEA overflow"
20647         stat $DIR/$tdir/guard || error "(4) Fail to stat"
20648         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
20649         [ $linkcount -eq 1001 ] ||
20650                 error "(5) Unexpected hard links count: $linkcount"
20651
20652         echo "List all links start at $(date)"
20653         ls -l $DIR/$tdir/foo > /dev/null ||
20654                 error "(6) Fail to list $DIR/$tdir/foo"
20655
20656         echo "Unlink hard links start at $(date)"
20657         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20658                 error "(7) Fail to unlink"
20659         echo "Unlink hard links finished at $(date)"
20660 }
20661 run_test 409 "Large amount of cross-MDTs hard links on the same file"
20662
20663 test_410()
20664 {
20665         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
20666                 skip "Need client version at least 2.9.59"
20667
20668         # Create a file, and stat it from the kernel
20669         local testfile=$DIR/$tfile
20670         touch $testfile
20671
20672         local run_id=$RANDOM
20673         local my_ino=$(stat --format "%i" $testfile)
20674
20675         # Try to insert the module. This will always fail as the
20676         # module is designed to not be inserted.
20677         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
20678             &> /dev/null
20679
20680         # Anything but success is a test failure
20681         dmesg | grep -q \
20682             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
20683             error "no inode match"
20684 }
20685 run_test 410 "Test inode number returned from kernel thread"
20686
20687 cleanup_test411_cgroup() {
20688         trap 0
20689         rmdir "$1"
20690 }
20691
20692 test_411() {
20693         local cg_basedir=/sys/fs/cgroup/memory
20694         # LU-9966
20695         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
20696                 skip "no setup for cgroup"
20697
20698         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
20699                 error "test file creation failed"
20700         cancel_lru_locks osc
20701
20702         # Create a very small memory cgroup to force a slab allocation error
20703         local cgdir=$cg_basedir/osc_slab_alloc
20704         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
20705         trap "cleanup_test411_cgroup $cgdir" EXIT
20706         echo 2M > $cgdir/memory.kmem.limit_in_bytes
20707         echo 1M > $cgdir/memory.limit_in_bytes
20708
20709         # Should not LBUG, just be killed by oom-killer
20710         # dd will return 0 even allocation failure in some environment.
20711         # So don't check return value
20712         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
20713         cleanup_test411_cgroup $cgdir
20714
20715         return 0
20716 }
20717 run_test 411 "Slab allocation error with cgroup does not LBUG"
20718
20719 test_412() {
20720         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20721         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20722                 skip "Need server version at least 2.10.55"
20723         fi
20724
20725         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
20726                 error "mkdir failed"
20727         $LFS getdirstripe $DIR/$tdir
20728         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20729         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
20730                 error "expect $((MDSCOUT - 1)) get $stripe_index"
20731         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
20732         [ $stripe_count -eq 2 ] ||
20733                 error "expect 2 get $stripe_count"
20734 }
20735 run_test 412 "mkdir on specific MDTs"
20736
20737 test_413a() {
20738         [ $MDSCOUNT -lt 2 ] &&
20739                 skip "We need at least 2 MDTs for this test"
20740
20741         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20742                 skip "Need server version at least 2.10.55"
20743         fi
20744
20745         mkdir $DIR/$tdir || error "mkdir failed"
20746
20747         # find MDT that is the most full
20748         local max=$($LFS df | grep MDT |
20749                 awk 'BEGIN { a=0 }
20750                         { sub("%", "", $5)
20751                           if (0+$5 >= a)
20752                           {
20753                                 a = $5
20754                                 b = $6
20755                           }
20756                         }
20757                      END { split(b, c, ":")
20758                            sub("]", "", c[2])
20759                            print c[2]
20760                          }')
20761
20762         for i in $(seq $((MDSCOUNT - 1))); do
20763                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
20764                         error "mkdir d$i failed"
20765                 $LFS getdirstripe $DIR/$tdir/d$i
20766                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
20767                 [ $stripe_index -ne $max ] ||
20768                         error "don't expect $max"
20769         done
20770 }
20771 run_test 413a "mkdir on less full MDTs"
20772
20773 test_413b() {
20774         [ $MDSCOUNT -lt 2 ] &&
20775                 skip "We need at least 2 MDTs for this test"
20776
20777         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
20778                 skip "Need server version at least 2.12.52"
20779
20780         mkdir $DIR/$tdir || error "mkdir failed"
20781         $LFS setdirstripe -D -i -1 -H space $DIR/$tdir ||
20782                 error "setdirstripe failed"
20783
20784         local qos_prio_free
20785         local qos_threshold_rr
20786         local count
20787
20788         qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
20789         qos_prio_free=${qos_prio_free%%%}
20790         qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr | head -n1)
20791         qos_threshold_rr=${qos_threshold_rr%%%}
20792         qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
20793
20794         stack_trap "$LCTL set_param lmv.*.qos_prio_free=$qos_prio_free" EXIT
20795         stack_trap "$LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr" \
20796                 EXIT
20797         stack_trap "$LCTL set_param lmv.*.qos_maxage=$qos_maxage" EXIT
20798
20799         echo "mkdir with roundrobin"
20800
20801         $LCTL set_param lmv.*.qos_threshold_rr=100
20802         for i in $(seq $((100 * MDSCOUNT))); do
20803                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20804         done
20805         for i in $(seq $MDSCOUNT); do
20806                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20807                         wc -w)
20808                 echo "$count directories created on MDT$((i - 1))"
20809                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
20810         done
20811
20812         rm -rf $DIR/$tdir/*
20813
20814         $LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr
20815         # Shorten statfs result age, so that it can be updated in time
20816         $LCTL set_param lmv.*.qos_maxage=1
20817         sleep_maxage
20818
20819         local ffree
20820         local bavail
20821         local max
20822         local min
20823         local max_index
20824         local min_index
20825         local tmp
20826
20827         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
20828         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
20829         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
20830
20831         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
20832         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
20833         max_index=0
20834         min_index=0
20835         for ((i = 1; i < ${#ffree[@]}; i++)); do
20836                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
20837                 if [ $tmp -gt $max ]; then
20838                         max=$tmp
20839                         max_index=$i
20840                 fi
20841                 if [ $tmp -lt $min ]; then
20842                         min=$tmp
20843                         min_index=$i
20844                 fi
20845         done
20846
20847         [ ${ffree[min_index]} -eq 0 ] &&
20848                 skip "no free files in MDT$min_index"
20849         [ ${ffree[min_index]} -gt 100000000 ] &&
20850                 skip "too much free files in MDT$min_index"
20851
20852         # Check if we need to generate uneven MDTs
20853         local threshold=50
20854         local diff=$(((max - min ) * 100 / min))
20855         local value="$(generate_string 1024)"
20856         local i
20857
20858         while [ $diff -lt $threshold ]; do
20859                 # generate uneven MDTs, create till $threshold% diff
20860                 echo -n "weight diff=$diff% must be > $threshold% ..."
20861                 count=$((${ffree[min_index]} / 10))
20862                 # 50 sec per 10000 files in vm
20863                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
20864                         skip "$count files to create"
20865                 echo "Fill MDT$min_index with $count files"
20866                 [ -d $DIR/$tdir-MDT$min_index ] ||
20867                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
20868                         error "mkdir $tdir-MDT$min_index failed"
20869                 for i in $(seq $count); do
20870                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
20871                                 $DIR/$tdir-MDT$min_index/f$i > /dev/null ||
20872                                 error "create f$i failed"
20873                         setfattr -n user.413b -v $value \
20874                                 $DIR/$tdir-MDT$min_index/f$i ||
20875                                 error "setfattr f$i failed"
20876                 done
20877
20878                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
20879                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
20880                 max=$(((${ffree[max_index]} >> 8) * \
20881                         (${bavail[max_index]} * bsize >> 16)))
20882                 min=$(((${ffree[min_index]} >> 8) * \
20883                         (${bavail[min_index]} * bsize >> 16)))
20884                 diff=$(((max - min) * 100 / min))
20885         done
20886
20887         echo "MDT filesfree available: ${ffree[@]}"
20888         echo "MDT blocks available: ${bavail[@]}"
20889         echo "weight diff=$diff%"
20890
20891         echo "mkdir with balanced space usage"
20892         $LCTL set_param lmv.*.qos_prio_free=100
20893         for i in $(seq $((100 * MDSCOUNT))); do
20894                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20895         done
20896
20897         for i in $(seq $MDSCOUNT); do
20898                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20899                         wc -w)
20900                 echo "$count directories created on MDT$((i - 1))"
20901         done
20902
20903         max=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$max_index$ | wc -l)
20904         min=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$min_index$ | wc -l)
20905
20906         [ $((max - min)) -lt 10 ] &&
20907                 error "subdirs shouldn't be evenly distributed"
20908
20909         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20910
20911         $LFS setdirstripe -D -d $DIR/$tdir || error "setdirstripe -d failed"
20912         getfattr -n trusted.dmv $DIR/$tdir &&
20913                 error "default dir layout exists" || true
20914 }
20915 run_test 413b "mkdir with balanced space usage"
20916
20917 test_414() {
20918 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
20919         $LCTL set_param fail_loc=0x80000521
20920         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
20921         rm -f $DIR/$tfile
20922 }
20923 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
20924
20925 test_415() {
20926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20927         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
20928                 skip "Need server version at least 2.11.52"
20929
20930         # LU-11102
20931         local total
20932         local setattr_pid
20933         local start_time
20934         local end_time
20935         local duration
20936
20937         total=500
20938         # this test may be slow on ZFS
20939         [ "$mds1_FSTYPE" == "zfs" ] && total=100
20940
20941         # though this test is designed for striped directory, let's test normal
20942         # directory too since lock is always saved as CoS lock.
20943         test_mkdir $DIR/$tdir || error "mkdir $tdir"
20944         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
20945
20946         (
20947                 while true; do
20948                         touch $DIR/$tdir
20949                 done
20950         ) &
20951         setattr_pid=$!
20952
20953         start_time=$(date +%s)
20954         for i in $(seq $total); do
20955                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
20956                         > /dev/null
20957         done
20958         end_time=$(date +%s)
20959         duration=$((end_time - start_time))
20960
20961         kill -9 $setattr_pid
20962
20963         echo "rename $total files took $duration sec"
20964         [ $duration -lt 100 ] || error "rename took $duration sec"
20965 }
20966 run_test 415 "lock revoke is not missing"
20967
20968 test_416() {
20969         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
20970                 skip "Need server version at least 2.11.55"
20971
20972         # define OBD_FAIL_OSD_TXN_START    0x19a
20973         do_facet mds1 lctl set_param fail_loc=0x19a
20974
20975         lfs mkdir -c $MDSCOUNT $DIR/$tdir
20976
20977         true
20978 }
20979 run_test 416 "transaction start failure won't cause system hung"
20980
20981 cleanup_417() {
20982         trap 0
20983         do_nodes $(comma_list $(mdts_nodes)) \
20984                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
20985         do_nodes $(comma_list $(mdts_nodes)) \
20986                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
20987         do_nodes $(comma_list $(mdts_nodes)) \
20988                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
20989 }
20990
20991 test_417() {
20992         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20993         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
20994                 skip "Need MDS version at least 2.11.56"
20995
20996         trap cleanup_417 RETURN EXIT
20997
20998         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
20999         do_nodes $(comma_list $(mdts_nodes)) \
21000                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
21001         $LFS migrate -m 0 $DIR/$tdir.1 &&
21002                 error "migrate dir $tdir.1 should fail"
21003
21004         do_nodes $(comma_list $(mdts_nodes)) \
21005                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
21006         $LFS mkdir -i 1 $DIR/$tdir.2 &&
21007                 error "create remote dir $tdir.2 should fail"
21008
21009         do_nodes $(comma_list $(mdts_nodes)) \
21010                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
21011         $LFS mkdir -c 2 $DIR/$tdir.3 &&
21012                 error "create striped dir $tdir.3 should fail"
21013         true
21014 }
21015 run_test 417 "disable remote dir, striped dir and dir migration"
21016
21017 # Checks that the outputs of df [-i] and lfs df [-i] match
21018 #
21019 # usage: check_lfs_df <blocks | inodes> <mountpoint>
21020 check_lfs_df() {
21021         local dir=$2
21022         local inodes
21023         local df_out
21024         local lfs_df_out
21025         local count
21026         local passed=false
21027
21028         # blocks or inodes
21029         [ "$1" == "blocks" ] && inodes= || inodes="-i"
21030
21031         for count in {1..100}; do
21032                 cancel_lru_locks
21033                 sync; sleep 0.2
21034
21035                 # read the lines of interest
21036                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
21037                         error "df $inodes $dir | tail -n +2 failed"
21038                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
21039                         error "lfs df $inodes $dir | grep summary: failed"
21040
21041                 # skip first substrings of each output as they are different
21042                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
21043                 # compare the two outputs
21044                 passed=true
21045                 for i in {1..5}; do
21046                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
21047                 done
21048                 $passed && break
21049         done
21050
21051         if ! $passed; then
21052                 df -P $inodes $dir
21053                 echo
21054                 lfs df $inodes $dir
21055                 error "df and lfs df $1 output mismatch: "      \
21056                       "df ${inodes}: ${df_out[*]}, "            \
21057                       "lfs df ${inodes}: ${lfs_df_out[*]}"
21058         fi
21059 }
21060
21061 test_418() {
21062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21063
21064         local dir=$DIR/$tdir
21065         local numfiles=$((RANDOM % 4096 + 2))
21066         local numblocks=$((RANDOM % 256 + 1))
21067
21068         wait_delete_completed
21069         test_mkdir $dir
21070
21071         # check block output
21072         check_lfs_df blocks $dir
21073         # check inode output
21074         check_lfs_df inodes $dir
21075
21076         # create a single file and retest
21077         echo "Creating a single file and testing"
21078         createmany -o $dir/$tfile- 1 &>/dev/null ||
21079                 error "creating 1 file in $dir failed"
21080         check_lfs_df blocks $dir
21081         check_lfs_df inodes $dir
21082
21083         # create a random number of files
21084         echo "Creating $((numfiles - 1)) files and testing"
21085         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
21086                 error "creating $((numfiles - 1)) files in $dir failed"
21087
21088         # write a random number of blocks to the first test file
21089         echo "Writing $numblocks 4K blocks and testing"
21090         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
21091                 count=$numblocks &>/dev/null ||
21092                 error "dd to $dir/${tfile}-0 failed"
21093
21094         # retest
21095         check_lfs_df blocks $dir
21096         check_lfs_df inodes $dir
21097
21098         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
21099                 error "unlinking $numfiles files in $dir failed"
21100 }
21101 run_test 418 "df and lfs df outputs match"
21102
21103 test_419()
21104 {
21105         local dir=$DIR/$tdir
21106
21107         mkdir -p $dir
21108         touch $dir/file
21109
21110         cancel_lru_locks mdc
21111
21112         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
21113         $LCTL set_param fail_loc=0x1410
21114         cat $dir/file
21115         $LCTL set_param fail_loc=0
21116         rm -rf $dir
21117 }
21118 run_test 419 "Verify open file by name doesn't crash kernel"
21119
21120 test_420()
21121 {
21122         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
21123                 skip "Need MDS version at least 2.12.53"
21124
21125         local SAVE_UMASK=$(umask)
21126         local dir=$DIR/$tdir
21127         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
21128
21129         mkdir -p $dir
21130         umask 0000
21131         mkdir -m03777 $dir/testdir
21132         ls -dn $dir/testdir
21133         # Need to remove trailing '.' when SELinux is enabled
21134         local dirperms=$(ls -dn $dir/testdir |
21135                          awk '{ sub(/\.$/, "", $1); print $1}')
21136         [ $dirperms == "drwxrwsrwt" ] ||
21137                 error "incorrect perms on $dir/testdir"
21138
21139         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
21140                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
21141         ls -n $dir/testdir/testfile
21142         local fileperms=$(ls -n $dir/testdir/testfile |
21143                           awk '{ sub(/\.$/, "", $1); print $1}')
21144         [ $fileperms == "-rwxr-xr-x" ] ||
21145                 error "incorrect perms on $dir/testdir/testfile"
21146
21147         umask $SAVE_UMASK
21148 }
21149 run_test 420 "clear SGID bit on non-directories for non-members"
21150
21151 test_421a() {
21152         local cnt
21153         local fid1
21154         local fid2
21155
21156         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21157                 skip "Need MDS version at least 2.12.54"
21158
21159         test_mkdir $DIR/$tdir
21160         createmany -o $DIR/$tdir/f 3
21161         cnt=$(ls -1 $DIR/$tdir | wc -l)
21162         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21163
21164         fid1=$(lfs path2fid $DIR/$tdir/f1)
21165         fid2=$(lfs path2fid $DIR/$tdir/f2)
21166         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
21167
21168         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
21169         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
21170
21171         cnt=$(ls -1 $DIR/$tdir | wc -l)
21172         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21173
21174         rm -f $DIR/$tdir/f3 || error "can't remove f3"
21175         createmany -o $DIR/$tdir/f 3
21176         cnt=$(ls -1 $DIR/$tdir | wc -l)
21177         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21178
21179         fid1=$(lfs path2fid $DIR/$tdir/f1)
21180         fid2=$(lfs path2fid $DIR/$tdir/f2)
21181         echo "remove using fsname $FSNAME"
21182         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
21183
21184         cnt=$(ls -1 $DIR/$tdir | wc -l)
21185         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21186 }
21187 run_test 421a "simple rm by fid"
21188
21189 test_421b() {
21190         local cnt
21191         local FID1
21192         local FID2
21193
21194         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21195                 skip "Need MDS version at least 2.12.54"
21196
21197         test_mkdir $DIR/$tdir
21198         createmany -o $DIR/$tdir/f 3
21199         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
21200         MULTIPID=$!
21201
21202         FID1=$(lfs path2fid $DIR/$tdir/f1)
21203         FID2=$(lfs path2fid $DIR/$tdir/f2)
21204         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
21205
21206         kill -USR1 $MULTIPID
21207         wait
21208
21209         cnt=$(ls $DIR/$tdir | wc -l)
21210         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
21211 }
21212 run_test 421b "rm by fid on open file"
21213
21214 test_421c() {
21215         local cnt
21216         local FIDS
21217
21218         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21219                 skip "Need MDS version at least 2.12.54"
21220
21221         test_mkdir $DIR/$tdir
21222         createmany -o $DIR/$tdir/f 3
21223         touch $DIR/$tdir/$tfile
21224         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
21225         cnt=$(ls -1 $DIR/$tdir | wc -l)
21226         [ $cnt != 184 ] && error "unexpected #files: $cnt"
21227
21228         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
21229         $LFS rmfid $DIR $FID1 || error "rmfid failed"
21230
21231         cnt=$(ls $DIR/$tdir | wc -l)
21232         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
21233 }
21234 run_test 421c "rm by fid against hardlinked files"
21235
21236 test_421d() {
21237         local cnt
21238         local FIDS
21239
21240         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21241                 skip "Need MDS version at least 2.12.54"
21242
21243         test_mkdir $DIR/$tdir
21244         createmany -o $DIR/$tdir/f 4097
21245         cnt=$(ls -1 $DIR/$tdir | wc -l)
21246         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
21247
21248         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
21249         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21250
21251         cnt=$(ls $DIR/$tdir | wc -l)
21252         rm -rf $DIR/$tdir
21253         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21254 }
21255 run_test 421d "rmfid en masse"
21256
21257 test_421e() {
21258         local cnt
21259         local FID
21260
21261         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21262         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21263                 skip "Need MDS version at least 2.12.54"
21264
21265         mkdir -p $DIR/$tdir
21266         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21267         createmany -o $DIR/$tdir/striped_dir/f 512
21268         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21269         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21270
21271         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21272                 sed "s/[/][^:]*://g")
21273         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21274
21275         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21276         rm -rf $DIR/$tdir
21277         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21278 }
21279 run_test 421e "rmfid in DNE"
21280
21281 test_421f() {
21282         local cnt
21283         local FID
21284
21285         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21286                 skip "Need MDS version at least 2.12.54"
21287
21288         test_mkdir $DIR/$tdir
21289         touch $DIR/$tdir/f
21290         cnt=$(ls -1 $DIR/$tdir | wc -l)
21291         [ $cnt != 1 ] && error "unexpected #files: $cnt"
21292
21293         FID=$(lfs path2fid $DIR/$tdir/f)
21294         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
21295         # rmfid should fail
21296         cnt=$(ls -1 $DIR/$tdir | wc -l)
21297         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
21298
21299         chmod a+rw $DIR/$tdir
21300         ls -la $DIR/$tdir
21301         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
21302         # rmfid should fail
21303         cnt=$(ls -1 $DIR/$tdir | wc -l)
21304         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
21305
21306         rm -f $DIR/$tdir/f
21307         $RUNAS touch $DIR/$tdir/f
21308         FID=$(lfs path2fid $DIR/$tdir/f)
21309         echo "rmfid as root"
21310         $LFS rmfid $DIR $FID || error "rmfid as root failed"
21311         cnt=$(ls -1 $DIR/$tdir | wc -l)
21312         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
21313
21314         rm -f $DIR/$tdir/f
21315         $RUNAS touch $DIR/$tdir/f
21316         cnt=$(ls -1 $DIR/$tdir | wc -l)
21317         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
21318         FID=$(lfs path2fid $DIR/$tdir/f)
21319         # rmfid w/o user_fid2path mount option should fail
21320         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
21321         cnt=$(ls -1 $DIR/$tdir | wc -l)
21322         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
21323
21324         umount_client $MOUNT || error "failed to umount client"
21325         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
21326                 error "failed to mount client'"
21327
21328         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
21329         # rmfid should succeed
21330         cnt=$(ls -1 $DIR/$tdir | wc -l)
21331         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
21332
21333         # rmfid shouldn't allow to remove files due to dir's permission
21334         chmod a+rwx $DIR/$tdir
21335         touch $DIR/$tdir/f
21336         ls -la $DIR/$tdir
21337         FID=$(lfs path2fid $DIR/$tdir/f)
21338         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
21339
21340         umount_client $MOUNT || error "failed to umount client"
21341         mount_client $MOUNT "$MOUNT_OPTS" ||
21342                 error "failed to mount client'"
21343
21344 }
21345 run_test 421f "rmfid checks permissions"
21346
21347 test_421g() {
21348         local cnt
21349         local FIDS
21350
21351         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21352         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21353                 skip "Need MDS version at least 2.12.54"
21354
21355         mkdir -p $DIR/$tdir
21356         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21357         createmany -o $DIR/$tdir/striped_dir/f 512
21358         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21359         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21360
21361         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21362                 sed "s/[/][^:]*://g")
21363
21364         rm -f $DIR/$tdir/striped_dir/f1*
21365         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21366         removed=$((512 - cnt))
21367
21368         # few files have been just removed, so we expect
21369         # rmfid to fail on their fids
21370         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
21371         [ $removed != $errors ] && error "$errors != $removed"
21372
21373         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21374         rm -rf $DIR/$tdir
21375         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21376 }
21377 run_test 421g "rmfid to return errors properly"
21378
21379 test_422() {
21380         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
21381         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
21382         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
21383         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
21384         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
21385
21386         local amc=$(at_max_get client)
21387         local amo=$(at_max_get mds1)
21388         local timeout=`lctl get_param -n timeout`
21389
21390         at_max_set 0 client
21391         at_max_set 0 mds1
21392
21393 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
21394         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
21395                         fail_val=$(((2*timeout + 10)*1000))
21396         touch $DIR/$tdir/d3/file &
21397         sleep 2
21398 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
21399         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
21400                         fail_val=$((2*timeout + 5))
21401         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
21402         local pid=$!
21403         sleep 1
21404         kill -9 $pid
21405         sleep $((2 * timeout))
21406         echo kill $pid
21407         kill -9 $pid
21408         lctl mark touch
21409         touch $DIR/$tdir/d2/file3
21410         touch $DIR/$tdir/d2/file4
21411         touch $DIR/$tdir/d2/file5
21412
21413         wait
21414         at_max_set $amc client
21415         at_max_set $amo mds1
21416
21417         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
21418         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
21419                 error "Watchdog is always throttled"
21420 }
21421 run_test 422 "kill a process with RPC in progress"
21422
21423 prep_801() {
21424         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21425         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21426                 skip "Need server version at least 2.9.55"
21427
21428         start_full_debug_logging
21429 }
21430
21431 post_801() {
21432         stop_full_debug_logging
21433 }
21434
21435 barrier_stat() {
21436         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21437                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21438                            awk '/The barrier for/ { print $7 }')
21439                 echo $st
21440         else
21441                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
21442                 echo \'$st\'
21443         fi
21444 }
21445
21446 barrier_expired() {
21447         local expired
21448
21449         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21450                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21451                           awk '/will be expired/ { print $7 }')
21452         else
21453                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
21454         fi
21455
21456         echo $expired
21457 }
21458
21459 test_801a() {
21460         prep_801
21461
21462         echo "Start barrier_freeze at: $(date)"
21463         #define OBD_FAIL_BARRIER_DELAY          0x2202
21464         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21465         # Do not reduce barrier time - See LU-11873
21466         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
21467
21468         sleep 2
21469         local b_status=$(barrier_stat)
21470         echo "Got barrier status at: $(date)"
21471         [ "$b_status" = "'freezing_p1'" ] ||
21472                 error "(1) unexpected barrier status $b_status"
21473
21474         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21475         wait
21476         b_status=$(barrier_stat)
21477         [ "$b_status" = "'frozen'" ] ||
21478                 error "(2) unexpected barrier status $b_status"
21479
21480         local expired=$(barrier_expired)
21481         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
21482         sleep $((expired + 3))
21483
21484         b_status=$(barrier_stat)
21485         [ "$b_status" = "'expired'" ] ||
21486                 error "(3) unexpected barrier status $b_status"
21487
21488         # Do not reduce barrier time - See LU-11873
21489         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
21490                 error "(4) fail to freeze barrier"
21491
21492         b_status=$(barrier_stat)
21493         [ "$b_status" = "'frozen'" ] ||
21494                 error "(5) unexpected barrier status $b_status"
21495
21496         echo "Start barrier_thaw at: $(date)"
21497         #define OBD_FAIL_BARRIER_DELAY          0x2202
21498         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21499         do_facet mgs $LCTL barrier_thaw $FSNAME &
21500
21501         sleep 2
21502         b_status=$(barrier_stat)
21503         echo "Got barrier status at: $(date)"
21504         [ "$b_status" = "'thawing'" ] ||
21505                 error "(6) unexpected barrier status $b_status"
21506
21507         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21508         wait
21509         b_status=$(barrier_stat)
21510         [ "$b_status" = "'thawed'" ] ||
21511                 error "(7) unexpected barrier status $b_status"
21512
21513         #define OBD_FAIL_BARRIER_FAILURE        0x2203
21514         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
21515         do_facet mgs $LCTL barrier_freeze $FSNAME
21516
21517         b_status=$(barrier_stat)
21518         [ "$b_status" = "'failed'" ] ||
21519                 error "(8) unexpected barrier status $b_status"
21520
21521         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21522         do_facet mgs $LCTL barrier_thaw $FSNAME
21523
21524         post_801
21525 }
21526 run_test 801a "write barrier user interfaces and stat machine"
21527
21528 test_801b() {
21529         prep_801
21530
21531         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21532         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
21533         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
21534         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
21535         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
21536
21537         cancel_lru_locks mdc
21538
21539         # 180 seconds should be long enough
21540         do_facet mgs $LCTL barrier_freeze $FSNAME 180
21541
21542         local b_status=$(barrier_stat)
21543         [ "$b_status" = "'frozen'" ] ||
21544                 error "(6) unexpected barrier status $b_status"
21545
21546         mkdir $DIR/$tdir/d0/d10 &
21547         mkdir_pid=$!
21548
21549         touch $DIR/$tdir/d1/f13 &
21550         touch_pid=$!
21551
21552         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
21553         ln_pid=$!
21554
21555         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
21556         mv_pid=$!
21557
21558         rm -f $DIR/$tdir/d4/f12 &
21559         rm_pid=$!
21560
21561         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
21562
21563         # To guarantee taht the 'stat' is not blocked
21564         b_status=$(barrier_stat)
21565         [ "$b_status" = "'frozen'" ] ||
21566                 error "(8) unexpected barrier status $b_status"
21567
21568         # let above commands to run at background
21569         sleep 5
21570
21571         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
21572         ps -p $touch_pid || error "(10) touch should be blocked"
21573         ps -p $ln_pid || error "(11) link should be blocked"
21574         ps -p $mv_pid || error "(12) rename should be blocked"
21575         ps -p $rm_pid || error "(13) unlink should be blocked"
21576
21577         b_status=$(barrier_stat)
21578         [ "$b_status" = "'frozen'" ] ||
21579                 error "(14) unexpected barrier status $b_status"
21580
21581         do_facet mgs $LCTL barrier_thaw $FSNAME
21582         b_status=$(barrier_stat)
21583         [ "$b_status" = "'thawed'" ] ||
21584                 error "(15) unexpected barrier status $b_status"
21585
21586         wait $mkdir_pid || error "(16) mkdir should succeed"
21587         wait $touch_pid || error "(17) touch should succeed"
21588         wait $ln_pid || error "(18) link should succeed"
21589         wait $mv_pid || error "(19) rename should succeed"
21590         wait $rm_pid || error "(20) unlink should succeed"
21591
21592         post_801
21593 }
21594 run_test 801b "modification will be blocked by write barrier"
21595
21596 test_801c() {
21597         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21598
21599         prep_801
21600
21601         stop mds2 || error "(1) Fail to stop mds2"
21602
21603         do_facet mgs $LCTL barrier_freeze $FSNAME 30
21604
21605         local b_status=$(barrier_stat)
21606         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
21607                 do_facet mgs $LCTL barrier_thaw $FSNAME
21608                 error "(2) unexpected barrier status $b_status"
21609         }
21610
21611         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21612                 error "(3) Fail to rescan barrier bitmap"
21613
21614         # Do not reduce barrier time - See LU-11873
21615         do_facet mgs $LCTL barrier_freeze $FSNAME 20
21616
21617         b_status=$(barrier_stat)
21618         [ "$b_status" = "'frozen'" ] ||
21619                 error "(4) unexpected barrier status $b_status"
21620
21621         do_facet mgs $LCTL barrier_thaw $FSNAME
21622         b_status=$(barrier_stat)
21623         [ "$b_status" = "'thawed'" ] ||
21624                 error "(5) unexpected barrier status $b_status"
21625
21626         local devname=$(mdsdevname 2)
21627
21628         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
21629
21630         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21631                 error "(7) Fail to rescan barrier bitmap"
21632
21633         post_801
21634 }
21635 run_test 801c "rescan barrier bitmap"
21636
21637 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
21638 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
21639 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
21640 saved_MOUNT_OPTS=$MOUNT_OPTS
21641
21642 cleanup_802a() {
21643         trap 0
21644
21645         stopall
21646         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
21647         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
21648         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
21649         MOUNT_OPTS=$saved_MOUNT_OPTS
21650         setupall
21651 }
21652
21653 test_802a() {
21654         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
21655         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21656         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21657                 skip "Need server version at least 2.9.55"
21658
21659         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
21660
21661         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21662
21663         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21664                 error "(2) Fail to copy"
21665
21666         trap cleanup_802a EXIT
21667
21668         # sync by force before remount as readonly
21669         sync; sync_all_data; sleep 3; sync_all_data
21670
21671         stopall
21672
21673         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
21674         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
21675         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
21676
21677         echo "Mount the server as read only"
21678         setupall server_only || error "(3) Fail to start servers"
21679
21680         echo "Mount client without ro should fail"
21681         mount_client $MOUNT &&
21682                 error "(4) Mount client without 'ro' should fail"
21683
21684         echo "Mount client with ro should succeed"
21685         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
21686         mount_client $MOUNT ||
21687                 error "(5) Mount client with 'ro' should succeed"
21688
21689         echo "Modify should be refused"
21690         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21691
21692         echo "Read should be allowed"
21693         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21694                 error "(7) Read should succeed under ro mode"
21695
21696         cleanup_802a
21697 }
21698 run_test 802a "simulate readonly device"
21699
21700 test_802b() {
21701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21702         remote_mds_nodsh && skip "remote MDS with nodsh"
21703
21704         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
21705                 skip "readonly option not available"
21706
21707         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
21708
21709         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21710                 error "(2) Fail to copy"
21711
21712         # write back all cached data before setting MDT to readonly
21713         cancel_lru_locks
21714         sync_all_data
21715
21716         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
21717         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
21718
21719         echo "Modify should be refused"
21720         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21721
21722         echo "Read should be allowed"
21723         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21724                 error "(7) Read should succeed under ro mode"
21725
21726         # disable readonly
21727         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
21728 }
21729 run_test 802b "be able to set MDTs to readonly"
21730
21731 test_803() {
21732         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21733         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21734                 skip "MDS needs to be newer than 2.10.54"
21735
21736         mkdir -p $DIR/$tdir
21737         # Create some objects on all MDTs to trigger related logs objects
21738         for idx in $(seq $MDSCOUNT); do
21739                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
21740                         $DIR/$tdir/dir${idx} ||
21741                         error "Fail to create $DIR/$tdir/dir${idx}"
21742         done
21743
21744         sync; sleep 3
21745         wait_delete_completed # ensure old test cleanups are finished
21746         echo "before create:"
21747         $LFS df -i $MOUNT
21748         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21749
21750         for i in {1..10}; do
21751                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
21752                         error "Fail to create $DIR/$tdir/foo$i"
21753         done
21754
21755         sync; sleep 3
21756         echo "after create:"
21757         $LFS df -i $MOUNT
21758         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21759
21760         # allow for an llog to be cleaned up during the test
21761         [ $after_used -ge $((before_used + 10 - 1)) ] ||
21762                 error "before ($before_used) + 10 > after ($after_used)"
21763
21764         for i in {1..10}; do
21765                 rm -rf $DIR/$tdir/foo$i ||
21766                         error "Fail to remove $DIR/$tdir/foo$i"
21767         done
21768
21769         sleep 3 # avoid MDT return cached statfs
21770         wait_delete_completed
21771         echo "after unlink:"
21772         $LFS df -i $MOUNT
21773         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21774
21775         # allow for an llog to be created during the test
21776         [ $after_used -le $((before_used + 1)) ] ||
21777                 error "after ($after_used) > before ($before_used) + 1"
21778 }
21779 run_test 803 "verify agent object for remote object"
21780
21781 test_804() {
21782         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21783         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21784                 skip "MDS needs to be newer than 2.10.54"
21785         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21786
21787         mkdir -p $DIR/$tdir
21788         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
21789                 error "Fail to create $DIR/$tdir/dir0"
21790
21791         local fid=$($LFS path2fid $DIR/$tdir/dir0)
21792         local dev=$(mdsdevname 2)
21793
21794         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21795                 grep ${fid} || error "NOT found agent entry for dir0"
21796
21797         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
21798                 error "Fail to create $DIR/$tdir/dir1"
21799
21800         touch $DIR/$tdir/dir1/foo0 ||
21801                 error "Fail to create $DIR/$tdir/dir1/foo0"
21802         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
21803         local rc=0
21804
21805         for idx in $(seq $MDSCOUNT); do
21806                 dev=$(mdsdevname $idx)
21807                 do_facet mds${idx} \
21808                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21809                         grep ${fid} && rc=$idx
21810         done
21811
21812         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
21813                 error "Fail to rename foo0 to foo1"
21814         if [ $rc -eq 0 ]; then
21815                 for idx in $(seq $MDSCOUNT); do
21816                         dev=$(mdsdevname $idx)
21817                         do_facet mds${idx} \
21818                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21819                         grep ${fid} && rc=$idx
21820                 done
21821         fi
21822
21823         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
21824                 error "Fail to rename foo1 to foo2"
21825         if [ $rc -eq 0 ]; then
21826                 for idx in $(seq $MDSCOUNT); do
21827                         dev=$(mdsdevname $idx)
21828                         do_facet mds${idx} \
21829                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21830                         grep ${fid} && rc=$idx
21831                 done
21832         fi
21833
21834         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
21835
21836         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
21837                 error "Fail to link to $DIR/$tdir/dir1/foo2"
21838         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
21839                 error "Fail to rename foo2 to foo0"
21840         unlink $DIR/$tdir/dir1/foo0 ||
21841                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
21842         rm -rf $DIR/$tdir/dir0 ||
21843                 error "Fail to rm $DIR/$tdir/dir0"
21844
21845         for idx in $(seq $MDSCOUNT); do
21846                 dev=$(mdsdevname $idx)
21847                 rc=0
21848
21849                 stop mds${idx}
21850                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
21851                         rc=$?
21852                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
21853                         error "mount mds$idx failed"
21854                 df $MOUNT > /dev/null 2>&1
21855
21856                 # e2fsck should not return error
21857                 [ $rc -eq 0 ] ||
21858                         error "e2fsck detected error on MDT${idx}: rc=$rc"
21859         done
21860 }
21861 run_test 804 "verify agent entry for remote entry"
21862
21863 cleanup_805() {
21864         do_facet $SINGLEMDS zfs set quota=$old $fsset
21865         unlinkmany $DIR/$tdir/f- 1000000
21866         trap 0
21867 }
21868
21869 test_805() {
21870         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
21871         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
21872         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
21873                 skip "netfree not implemented before 0.7"
21874         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
21875                 skip "Need MDS version at least 2.10.57"
21876
21877         local fsset
21878         local freekb
21879         local usedkb
21880         local old
21881         local quota
21882         local pref="osd-zfs.lustre-MDT0000."
21883
21884         # limit available space on MDS dataset to meet nospace issue
21885         # quickly. then ZFS 0.7.2 can use reserved space if asked
21886         # properly (using netfree flag in osd_declare_destroy()
21887         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
21888         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
21889                 gawk '{print $3}')
21890         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
21891         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
21892         let "usedkb=usedkb-freekb"
21893         let "freekb=freekb/2"
21894         if let "freekb > 5000"; then
21895                 let "freekb=5000"
21896         fi
21897         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
21898         trap cleanup_805 EXIT
21899         mkdir $DIR/$tdir
21900         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
21901         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
21902         rm -rf $DIR/$tdir || error "not able to remove"
21903         do_facet $SINGLEMDS zfs set quota=$old $fsset
21904         trap 0
21905 }
21906 run_test 805 "ZFS can remove from full fs"
21907
21908 # Size-on-MDS test
21909 check_lsom_data()
21910 {
21911         local file=$1
21912         local size=$($LFS getsom -s $file)
21913         local expect=$(stat -c %s $file)
21914
21915         [[ $size == $expect ]] ||
21916                 error "$file expected size: $expect, got: $size"
21917
21918         local blocks=$($LFS getsom -b $file)
21919         expect=$(stat -c %b $file)
21920         [[ $blocks == $expect ]] ||
21921                 error "$file expected blocks: $expect, got: $blocks"
21922 }
21923
21924 check_lsom_size()
21925 {
21926         local size=$($LFS getsom -s $1)
21927         local expect=$2
21928
21929         [[ $size == $expect ]] ||
21930                 error "$file expected size: $expect, got: $size"
21931 }
21932
21933 test_806() {
21934         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21935                 skip "Need MDS version at least 2.11.52"
21936
21937         local bs=1048576
21938
21939         touch $DIR/$tfile || error "touch $tfile failed"
21940
21941         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21942         save_lustre_params client "llite.*.xattr_cache" > $save
21943         lctl set_param llite.*.xattr_cache=0
21944         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21945
21946         # single-threaded write
21947         echo "Test SOM for single-threaded write"
21948         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
21949                 error "write $tfile failed"
21950         check_lsom_size $DIR/$tfile $bs
21951
21952         local num=32
21953         local size=$(($num * $bs))
21954         local offset=0
21955         local i
21956
21957         echo "Test SOM for single client multi-threaded($num) write"
21958         $TRUNCATE $DIR/$tfile 0
21959         for ((i = 0; i < $num; i++)); do
21960                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21961                 local pids[$i]=$!
21962                 offset=$((offset + $bs))
21963         done
21964         for (( i=0; i < $num; i++ )); do
21965                 wait ${pids[$i]}
21966         done
21967         check_lsom_size $DIR/$tfile $size
21968
21969         $TRUNCATE $DIR/$tfile 0
21970         for ((i = 0; i < $num; i++)); do
21971                 offset=$((offset - $bs))
21972                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21973                 local pids[$i]=$!
21974         done
21975         for (( i=0; i < $num; i++ )); do
21976                 wait ${pids[$i]}
21977         done
21978         check_lsom_size $DIR/$tfile $size
21979
21980         # multi-client writes
21981         num=$(get_node_count ${CLIENTS//,/ })
21982         size=$(($num * $bs))
21983         offset=0
21984         i=0
21985
21986         echo "Test SOM for multi-client ($num) writes"
21987         $TRUNCATE $DIR/$tfile 0
21988         for client in ${CLIENTS//,/ }; do
21989                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21990                 local pids[$i]=$!
21991                 i=$((i + 1))
21992                 offset=$((offset + $bs))
21993         done
21994         for (( i=0; i < $num; i++ )); do
21995                 wait ${pids[$i]}
21996         done
21997         check_lsom_size $DIR/$tfile $offset
21998
21999         i=0
22000         $TRUNCATE $DIR/$tfile 0
22001         for client in ${CLIENTS//,/ }; do
22002                 offset=$((offset - $bs))
22003                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22004                 local pids[$i]=$!
22005                 i=$((i + 1))
22006         done
22007         for (( i=0; i < $num; i++ )); do
22008                 wait ${pids[$i]}
22009         done
22010         check_lsom_size $DIR/$tfile $size
22011
22012         # verify truncate
22013         echo "Test SOM for truncate"
22014         $TRUNCATE $DIR/$tfile 1048576
22015         check_lsom_size $DIR/$tfile 1048576
22016         $TRUNCATE $DIR/$tfile 1234
22017         check_lsom_size $DIR/$tfile 1234
22018
22019         # verify SOM blocks count
22020         echo "Verify SOM block count"
22021         $TRUNCATE $DIR/$tfile 0
22022         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
22023                 error "failed to write file $tfile"
22024         check_lsom_data $DIR/$tfile
22025 }
22026 run_test 806 "Verify Lazy Size on MDS"
22027
22028 test_807() {
22029         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22030         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22031                 skip "Need MDS version at least 2.11.52"
22032
22033         # Registration step
22034         changelog_register || error "changelog_register failed"
22035         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
22036         changelog_users $SINGLEMDS | grep -q $cl_user ||
22037                 error "User $cl_user not found in changelog_users"
22038
22039         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22040         save_lustre_params client "llite.*.xattr_cache" > $save
22041         lctl set_param llite.*.xattr_cache=0
22042         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22043
22044         rm -rf $DIR/$tdir || error "rm $tdir failed"
22045         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22046         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
22047         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
22048         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
22049                 error "truncate $tdir/trunc failed"
22050
22051         local bs=1048576
22052         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
22053                 error "write $tfile failed"
22054
22055         # multi-client wirtes
22056         local num=$(get_node_count ${CLIENTS//,/ })
22057         local offset=0
22058         local i=0
22059
22060         echo "Test SOM for multi-client ($num) writes"
22061         touch $DIR/$tfile || error "touch $tfile failed"
22062         $TRUNCATE $DIR/$tfile 0
22063         for client in ${CLIENTS//,/ }; do
22064                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22065                 local pids[$i]=$!
22066                 i=$((i + 1))
22067                 offset=$((offset + $bs))
22068         done
22069         for (( i=0; i < $num; i++ )); do
22070                 wait ${pids[$i]}
22071         done
22072
22073         sleep 5
22074         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
22075         check_lsom_data $DIR/$tdir/trunc
22076         check_lsom_data $DIR/$tdir/single_dd
22077         check_lsom_data $DIR/$tfile
22078
22079         rm -rf $DIR/$tdir
22080         # Deregistration step
22081         changelog_deregister || error "changelog_deregister failed"
22082 }
22083 run_test 807 "verify LSOM syncing tool"
22084
22085 check_som_nologged()
22086 {
22087         local lines=$($LFS changelog $FSNAME-MDT0000 |
22088                 grep 'x=trusted.som' | wc -l)
22089         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
22090 }
22091
22092 test_808() {
22093         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22094                 skip "Need MDS version at least 2.11.55"
22095
22096         # Registration step
22097         changelog_register || error "changelog_register failed"
22098
22099         touch $DIR/$tfile || error "touch $tfile failed"
22100         check_som_nologged
22101
22102         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
22103                 error "write $tfile failed"
22104         check_som_nologged
22105
22106         $TRUNCATE $DIR/$tfile 1234
22107         check_som_nologged
22108
22109         $TRUNCATE $DIR/$tfile 1048576
22110         check_som_nologged
22111
22112         # Deregistration step
22113         changelog_deregister || error "changelog_deregister failed"
22114 }
22115 run_test 808 "Check trusted.som xattr not logged in Changelogs"
22116
22117 check_som_nodata()
22118 {
22119         $LFS getsom $1
22120         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
22121 }
22122
22123 test_809() {
22124         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22125                 skip "Need MDS version at least 2.11.56"
22126
22127         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
22128                 error "failed to create DoM-only file $DIR/$tfile"
22129         touch $DIR/$tfile || error "touch $tfile failed"
22130         check_som_nodata $DIR/$tfile
22131
22132         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
22133                 error "write $tfile failed"
22134         check_som_nodata $DIR/$tfile
22135
22136         $TRUNCATE $DIR/$tfile 1234
22137         check_som_nodata $DIR/$tfile
22138
22139         $TRUNCATE $DIR/$tfile 4097
22140         check_som_nodata $DIR/$file
22141 }
22142 run_test 809 "Verify no SOM xattr store for DoM-only files"
22143
22144 test_810() {
22145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22146         $GSS && skip_env "could not run with gss"
22147
22148         set_checksums 1
22149         stack_trap "set_checksums $ORIG_CSUM" EXIT
22150         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
22151
22152         local csum
22153         local before
22154         local after
22155         for csum in $CKSUM_TYPES; do
22156                 #define OBD_FAIL_OSC_NO_GRANT   0x411
22157                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
22158                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
22159                         eval set -- $i
22160                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
22161                         before=$(md5sum $DIR/$tfile)
22162                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
22163                         after=$(md5sum $DIR/$tfile)
22164                         [ "$before" == "$after" ] ||
22165                                 error "$csum: $before != $after bs=$1 seek=$2"
22166                 done
22167         done
22168 }
22169 run_test 810 "partial page writes on ZFS (LU-11663)"
22170
22171 test_811() {
22172         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
22173                 skip "Need MDS version at least 2.11.56"
22174
22175         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
22176         do_facet mds1 $LCTL set_param fail_loc=0x165
22177         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
22178
22179         stop mds1
22180         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22181
22182         sleep 5
22183         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
22184                 error "MDD orphan cleanup thread not quit"
22185 }
22186 run_test 811 "orphan name stub can be cleaned up in startup"
22187
22188 test_812() {
22189         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
22190                 skip "OST < 2.12.51 doesn't support this fail_loc"
22191         [ "$SHARED_KEY" = true ] &&
22192                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22193
22194         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22195         # ensure ost1 is connected
22196         stat $DIR/$tfile >/dev/null || error "can't stat"
22197         wait_osc_import_state client ost1 FULL
22198         # no locks, no reqs to let the connection idle
22199         cancel_lru_locks osc
22200
22201         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
22202 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
22203         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
22204         wait_osc_import_state client ost1 CONNECTING
22205         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
22206
22207         stat $DIR/$tfile >/dev/null || error "can't stat file"
22208 }
22209 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
22210
22211 test_813() {
22212         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
22213         [ -z "$file_heat_sav" ] && skip "no file heat support"
22214
22215         local readsample
22216         local writesample
22217         local readbyte
22218         local writebyte
22219         local readsample1
22220         local writesample1
22221         local readbyte1
22222         local writebyte1
22223
22224         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
22225         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
22226
22227         $LCTL set_param -n llite.*.file_heat=1
22228         echo "Turn on file heat"
22229         echo "Period second: $period_second, Decay percentage: $decay_pct"
22230
22231         echo "QQQQ" > $DIR/$tfile
22232         echo "QQQQ" > $DIR/$tfile
22233         echo "QQQQ" > $DIR/$tfile
22234         cat $DIR/$tfile > /dev/null
22235         cat $DIR/$tfile > /dev/null
22236         cat $DIR/$tfile > /dev/null
22237         cat $DIR/$tfile > /dev/null
22238
22239         local out=$($LFS heat_get $DIR/$tfile)
22240
22241         $LFS heat_get $DIR/$tfile
22242         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22243         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22244         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22245         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22246
22247         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
22248         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
22249         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
22250         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
22251
22252         sleep $((period_second + 3))
22253         echo "Sleep $((period_second + 3)) seconds..."
22254         # The recursion formula to calculate the heat of the file f is as
22255         # follow:
22256         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
22257         # Where Hi is the heat value in the period between time points i*I and
22258         # (i+1)*I; Ci is the access count in the period; the symbol P refers
22259         # to the weight of Ci.
22260         out=$($LFS heat_get $DIR/$tfile)
22261         $LFS heat_get $DIR/$tfile
22262         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22263         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22264         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22265         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22266
22267         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
22268                 error "read sample ($readsample) is wrong"
22269         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
22270                 error "write sample ($writesample) is wrong"
22271         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
22272                 error "read bytes ($readbyte) is wrong"
22273         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
22274                 error "write bytes ($writebyte) is wrong"
22275
22276         echo "QQQQ" > $DIR/$tfile
22277         echo "QQQQ" > $DIR/$tfile
22278         echo "QQQQ" > $DIR/$tfile
22279         cat $DIR/$tfile > /dev/null
22280         cat $DIR/$tfile > /dev/null
22281         cat $DIR/$tfile > /dev/null
22282         cat $DIR/$tfile > /dev/null
22283
22284         sleep $((period_second + 3))
22285         echo "Sleep $((period_second + 3)) seconds..."
22286
22287         out=$($LFS heat_get $DIR/$tfile)
22288         $LFS heat_get $DIR/$tfile
22289         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22290         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22291         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22292         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22293
22294         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
22295                 4 * $decay_pct) / 100") -eq 1 ] ||
22296                 error "read sample ($readsample1) is wrong"
22297         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
22298                 3 * $decay_pct) / 100") -eq 1 ] ||
22299                 error "write sample ($writesample1) is wrong"
22300         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
22301                 20 * $decay_pct) / 100") -eq 1 ] ||
22302                 error "read bytes ($readbyte1) is wrong"
22303         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
22304                 15 * $decay_pct) / 100") -eq 1 ] ||
22305                 error "write bytes ($writebyte1) is wrong"
22306
22307         echo "Turn off file heat for the file $DIR/$tfile"
22308         $LFS heat_set -o $DIR/$tfile
22309
22310         echo "QQQQ" > $DIR/$tfile
22311         echo "QQQQ" > $DIR/$tfile
22312         echo "QQQQ" > $DIR/$tfile
22313         cat $DIR/$tfile > /dev/null
22314         cat $DIR/$tfile > /dev/null
22315         cat $DIR/$tfile > /dev/null
22316         cat $DIR/$tfile > /dev/null
22317
22318         out=$($LFS heat_get $DIR/$tfile)
22319         $LFS heat_get $DIR/$tfile
22320         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22321         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22322         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22323         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22324
22325         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22326         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22327         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22328         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22329
22330         echo "Trun on file heat for the file $DIR/$tfile"
22331         $LFS heat_set -O $DIR/$tfile
22332
22333         echo "QQQQ" > $DIR/$tfile
22334         echo "QQQQ" > $DIR/$tfile
22335         echo "QQQQ" > $DIR/$tfile
22336         cat $DIR/$tfile > /dev/null
22337         cat $DIR/$tfile > /dev/null
22338         cat $DIR/$tfile > /dev/null
22339         cat $DIR/$tfile > /dev/null
22340
22341         out=$($LFS heat_get $DIR/$tfile)
22342         $LFS heat_get $DIR/$tfile
22343         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22344         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22345         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22346         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22347
22348         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
22349         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
22350         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
22351         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
22352
22353         $LFS heat_set -c $DIR/$tfile
22354         $LCTL set_param -n llite.*.file_heat=0
22355         echo "Turn off file heat support for the Lustre filesystem"
22356
22357         echo "QQQQ" > $DIR/$tfile
22358         echo "QQQQ" > $DIR/$tfile
22359         echo "QQQQ" > $DIR/$tfile
22360         cat $DIR/$tfile > /dev/null
22361         cat $DIR/$tfile > /dev/null
22362         cat $DIR/$tfile > /dev/null
22363         cat $DIR/$tfile > /dev/null
22364
22365         out=$($LFS heat_get $DIR/$tfile)
22366         $LFS heat_get $DIR/$tfile
22367         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22368         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22369         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22370         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22371
22372         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22373         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22374         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22375         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22376
22377         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
22378         rm -f $DIR/$tfile
22379 }
22380 run_test 813 "File heat verfication"
22381
22382 test_814()
22383 {
22384         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
22385         echo -n y >> $DIR/$tfile
22386         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
22387         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
22388 }
22389 run_test 814 "sparse cp works as expected (LU-12361)"
22390
22391 test_815()
22392 {
22393         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
22394         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
22395 }
22396 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
22397
22398 test_816() {
22399         [ "$SHARED_KEY" = true ] &&
22400                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22401
22402         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22403         # ensure ost1 is connected
22404         stat $DIR/$tfile >/dev/null || error "can't stat"
22405         wait_osc_import_state client ost1 FULL
22406         # no locks, no reqs to let the connection idle
22407         cancel_lru_locks osc
22408         lru_resize_disable osc
22409         local before
22410         local now
22411         before=$($LCTL get_param -n \
22412                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22413
22414         wait_osc_import_state client ost1 IDLE
22415         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
22416         now=$($LCTL get_param -n \
22417               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22418         [ $before == $now ] || error "lru_size changed $before != $now"
22419 }
22420 run_test 816 "do not reset lru_resize on idle reconnect"
22421
22422 cleanup_817() {
22423         umount $tmpdir
22424         exportfs -u localhost:$DIR/nfsexp
22425         rm -rf $DIR/nfsexp
22426 }
22427
22428 test_817() {
22429         systemctl restart nfs-server.service || skip "failed to restart nfsd"
22430
22431         mkdir -p $DIR/nfsexp
22432         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
22433                 error "failed to export nfs"
22434
22435         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
22436         stack_trap cleanup_817 EXIT
22437
22438         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
22439                 error "failed to mount nfs to $tmpdir"
22440
22441         cp /bin/true $tmpdir
22442         $DIR/nfsexp/true || error "failed to execute 'true' command"
22443 }
22444 run_test 817 "nfsd won't cache write lock for exec file"
22445
22446 test_818() {
22447         mkdir $DIR/$tdir
22448         $LFS setstripe -c1 -i0 $DIR/$tfile
22449         $LFS setstripe -c1 -i1 $DIR/$tfile
22450         stop $SINGLEMDS
22451         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
22452         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
22453         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
22454                 error "start $SINGLEMDS failed"
22455         rm -rf $DIR/$tdir
22456 }
22457 run_test 818 "unlink with failed llog"
22458
22459 test_819a() {
22460         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22461         cancel_lru_locks osc
22462         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22463         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22464         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
22465         rm -f $TDIR/$tfile
22466 }
22467 run_test 819a "too big niobuf in read"
22468
22469 test_819b() {
22470         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22471         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22472         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22473         cancel_lru_locks osc
22474         sleep 1
22475         rm -f $TDIR/$tfile
22476 }
22477 run_test 819b "too big niobuf in write"
22478
22479 #
22480 # tests that do cleanup/setup should be run at the end
22481 #
22482
22483 test_900() {
22484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22485         local ls
22486
22487         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
22488         $LCTL set_param fail_loc=0x903
22489
22490         cancel_lru_locks MGC
22491
22492         FAIL_ON_ERROR=true cleanup
22493         FAIL_ON_ERROR=true setup
22494 }
22495 run_test 900 "umount should not race with any mgc requeue thread"
22496
22497 complete $SECONDS
22498 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
22499 check_and_cleanup_lustre
22500 if [ "$I_MOUNTED" != "yes" ]; then
22501         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
22502 fi
22503 exit_status