Whamcloud - gitweb
LU-4423 ptlrpc: remove inline on non-inlined functions.
[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-11594 LU-11667 LU-11729
57         ALWAYS_EXCEPT+=" 45       103a      317      810"
58 fi
59
60 #                                  5          12          (min)"
61 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
62
63 if [ "$mds1_FSTYPE" = "zfs" ]; then
64         # bug number for skipped test: LU-1957
65         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  180"
66         #                                               13    (min)"
67         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
68 fi
69
70 # Get the SLES distro version
71 #
72 # Returns a version string that should only be used in comparing
73 # strings returned by version_code()
74 sles_version_code()
75 {
76         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
77
78         # All SuSE Linux versions have one decimal. version_code expects two
79         local sles_version=$version.0
80         version_code $sles_version
81 }
82
83 # Check if we are running on Ubuntu or SLES so we can make decisions on
84 # what tests to run
85 if [ -r /etc/SuSE-release ]; then
86         sles_version=$(sles_version_code)
87         [ $sles_version -lt $(version_code 11.4.0) ] &&
88                 # bug number for skipped test: LU-4341
89                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
90         [ $sles_version -lt $(version_code 12.0.0) ] &&
91                 # bug number for skipped test: LU-3703
92                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
93 elif [ -r /etc/os-release ]; then
94         if grep -qi ubuntu /etc/os-release; then
95                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
96                                                 -e 's/^VERSION=//p' \
97                                                 /etc/os-release |
98                                                 awk '{ print $1 }'))
99
100                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
101                         # bug number for skipped test:
102                         #                LU-10334 LU-10366
103                         ALWAYS_EXCEPT+=" 103a     410"
104                 fi
105         fi
106 fi
107
108 build_test_filter
109 FAIL_ON_ERROR=false
110
111 cleanup() {
112         echo -n "cln.."
113         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
114         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
115 }
116 setup() {
117         echo -n "mnt.."
118         load_modules
119         setupall || exit 10
120         echo "done"
121 }
122
123 check_swap_layouts_support()
124 {
125         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
126                 skip "Does not support layout lock."
127 }
128
129 check_and_setup_lustre
130 DIR=${DIR:-$MOUNT}
131 assert_DIR
132
133 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
134
135 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
136 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
137 rm -rf $DIR/[Rdfs][0-9]*
138
139 # $RUNAS_ID may get set incorrectly somewhere else
140 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
141         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
142
143 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
144
145 if [ "${ONLY}" = "MOUNT" ] ; then
146         echo "Lustre is up, please go on"
147         exit
148 fi
149
150 echo "preparing for tests involving mounts"
151 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
152 touch $EXT2_DEV
153 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
154 echo # add a newline after mke2fs.
155
156 umask 077
157
158 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
159 lctl set_param debug=-1 2> /dev/null || true
160 test_0a() {
161         touch $DIR/$tfile
162         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
163         rm $DIR/$tfile
164         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
165 }
166 run_test 0a "touch; rm ====================="
167
168 test_0b() {
169         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
170         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
171 }
172 run_test 0b "chmod 0755 $DIR ============================="
173
174 test_0c() {
175         $LCTL get_param mdc.*.import | grep "state: FULL" ||
176                 error "import not FULL"
177         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
178                 error "bad target"
179 }
180 run_test 0c "check import proc"
181
182 test_0d() { # LU-3397
183         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
184                 skip "proc exports not supported before 2.10.57"
185
186         local mgs_exp="mgs.MGS.exports"
187         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
188         local exp_client_nid
189         local exp_client_version
190         local exp_val
191         local imp_val
192         local temp_imp=$DIR/$tfile.import
193         local temp_exp=$DIR/$tfile.export
194
195         # save mgc import file to $temp_imp
196         $LCTL get_param mgc.*.import | tee $temp_imp
197         # Check if client uuid is found in MGS export
198         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
199                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
200                         $client_uuid ] &&
201                         break;
202         done
203         # save mgs export file to $temp_exp
204         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
205
206         # Compare the value of field "connect_flags"
207         imp_val=$(grep "connect_flags" $temp_imp)
208         exp_val=$(grep "connect_flags" $temp_exp)
209         [ "$exp_val" == "$imp_val" ] ||
210                 error "export flags '$exp_val' != import flags '$imp_val'"
211
212         # Compare the value of client version
213         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
214         exp_val=$(version_code $exp_client_version)
215         imp_val=$CLIENT_VERSION
216         [ "$exp_val" == "$imp_val" ] ||
217                 error "export client version '$exp_val' != '$imp_val'"
218 }
219 run_test 0d "check export proc ============================="
220
221 test_1() {
222         test_mkdir $DIR/$tdir
223         test_mkdir $DIR/$tdir/d2
224         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
225         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
226         rmdir $DIR/$tdir/d2
227         rmdir $DIR/$tdir
228         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
229 }
230 run_test 1 "mkdir; remkdir; rmdir"
231
232 test_2() {
233         test_mkdir $DIR/$tdir
234         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
235         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
236         rm -r $DIR/$tdir
237         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
238 }
239 run_test 2 "mkdir; touch; rmdir; check file"
240
241 test_3() {
242         test_mkdir $DIR/$tdir
243         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
244         touch $DIR/$tdir/$tfile
245         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
246         rm -r $DIR/$tdir
247         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
248 }
249 run_test 3 "mkdir; touch; rmdir; check dir"
250
251 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
252 test_4() {
253         test_mkdir -i 1 $DIR/$tdir
254
255         touch $DIR/$tdir/$tfile ||
256                 error "Create file under remote directory failed"
257
258         rmdir $DIR/$tdir &&
259                 error "Expect error removing in-use dir $DIR/$tdir"
260
261         test -d $DIR/$tdir || error "Remote directory disappeared"
262
263         rm -rf $DIR/$tdir || error "remove remote dir error"
264 }
265 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
266
267 test_5() {
268         test_mkdir $DIR/$tdir
269         test_mkdir $DIR/$tdir/d2
270         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
271         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
272         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
273 }
274 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
275
276 test_6a() {
277         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
278         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
279         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
280                 error "$tfile does not have perm 0666 or UID $UID"
281         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
282         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
283                 error "$tfile should be 0666 and owned by UID $UID"
284 }
285 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
286
287 test_6c() {
288         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
289
290         touch $DIR/$tfile
291         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
292         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
293                 error "$tfile should be owned by UID $RUNAS_ID"
294         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
295         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
296                 error "$tfile should be owned by UID $RUNAS_ID"
297 }
298 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
299
300 test_6e() {
301         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
302
303         touch $DIR/$tfile
304         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
305         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
306                 error "$tfile should be owned by GID $UID"
307         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
308         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
309                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
310 }
311 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
312
313 test_6g() {
314         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
315
316         test_mkdir $DIR/$tdir
317         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
318         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
319         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
320         test_mkdir $DIR/$tdir/d/subdir
321         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
322                 error "$tdir/d/subdir should be GID $RUNAS_GID"
323         if [[ $MDSCOUNT -gt 1 ]]; then
324                 # check remote dir sgid inherite
325                 $LFS mkdir -i 0 $DIR/$tdir.local ||
326                         error "mkdir $tdir.local failed"
327                 chmod g+s $DIR/$tdir.local ||
328                         error "chmod $tdir.local failed"
329                 chgrp $RUNAS_GID $DIR/$tdir.local ||
330                         error "chgrp $tdir.local failed"
331                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
332                         error "mkdir $tdir.remote failed"
333                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
334                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
335                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
336                         error "$tdir.remote should be mode 02755"
337         fi
338 }
339 run_test 6g "verify new dir in sgid dir inherits group"
340
341 test_6h() { # bug 7331
342         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
343
344         touch $DIR/$tfile || error "touch failed"
345         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
346         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
347                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
348         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
349                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
350 }
351 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
352
353 test_7a() {
354         test_mkdir $DIR/$tdir
355         $MCREATE $DIR/$tdir/$tfile
356         chmod 0666 $DIR/$tdir/$tfile
357         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
358                 error "$tdir/$tfile should be mode 0666"
359 }
360 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
361
362 test_7b() {
363         if [ ! -d $DIR/$tdir ]; then
364                 test_mkdir $DIR/$tdir
365         fi
366         $MCREATE $DIR/$tdir/$tfile
367         echo -n foo > $DIR/$tdir/$tfile
368         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
369         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
370 }
371 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
372
373 test_8() {
374         test_mkdir $DIR/$tdir
375         touch $DIR/$tdir/$tfile
376         chmod 0666 $DIR/$tdir/$tfile
377         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
378                 error "$tfile mode not 0666"
379 }
380 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
381
382 test_9() {
383         test_mkdir $DIR/$tdir
384         test_mkdir $DIR/$tdir/d2
385         test_mkdir $DIR/$tdir/d2/d3
386         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
387 }
388 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
389
390 test_10() {
391         test_mkdir $DIR/$tdir
392         test_mkdir $DIR/$tdir/d2
393         touch $DIR/$tdir/d2/$tfile
394         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
395                 error "$tdir/d2/$tfile not a file"
396 }
397 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
398
399 test_11() {
400         test_mkdir $DIR/$tdir
401         test_mkdir $DIR/$tdir/d2
402         chmod 0666 $DIR/$tdir/d2
403         chmod 0705 $DIR/$tdir/d2
404         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
405                 error "$tdir/d2 mode not 0705"
406 }
407 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
408
409 test_12() {
410         test_mkdir $DIR/$tdir
411         touch $DIR/$tdir/$tfile
412         chmod 0666 $DIR/$tdir/$tfile
413         chmod 0654 $DIR/$tdir/$tfile
414         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
415                 error "$tdir/d2 mode not 0654"
416 }
417 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
418
419 test_13() {
420         test_mkdir $DIR/$tdir
421         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
422         >  $DIR/$tdir/$tfile
423         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
424                 error "$tdir/$tfile size not 0 after truncate"
425 }
426 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
427
428 test_14() {
429         test_mkdir $DIR/$tdir
430         touch $DIR/$tdir/$tfile
431         rm $DIR/$tdir/$tfile
432         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
433 }
434 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
435
436 test_15() {
437         test_mkdir $DIR/$tdir
438         touch $DIR/$tdir/$tfile
439         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
440         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
441                 error "$tdir/${tfile_2} not a file after rename"
442         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
443 }
444 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
445
446 test_16() {
447         test_mkdir $DIR/$tdir
448         touch $DIR/$tdir/$tfile
449         rm -rf $DIR/$tdir/$tfile
450         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
451 }
452 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
453
454 test_17a() {
455         test_mkdir $DIR/$tdir
456         touch $DIR/$tdir/$tfile
457         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
458         ls -l $DIR/$tdir
459         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
460                 error "$tdir/l-exist not a symlink"
461         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
462                 error "$tdir/l-exist not referencing a file"
463         rm -f $DIR/$tdir/l-exist
464         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
465 }
466 run_test 17a "symlinks: create, remove (real)"
467
468 test_17b() {
469         test_mkdir $DIR/$tdir
470         ln -s no-such-file $DIR/$tdir/l-dangle
471         ls -l $DIR/$tdir
472         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
473                 error "$tdir/l-dangle not referencing no-such-file"
474         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
475                 error "$tdir/l-dangle not referencing non-existent file"
476         rm -f $DIR/$tdir/l-dangle
477         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
478 }
479 run_test 17b "symlinks: create, remove (dangling)"
480
481 test_17c() { # bug 3440 - don't save failed open RPC for replay
482         test_mkdir $DIR/$tdir
483         ln -s foo $DIR/$tdir/$tfile
484         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
485 }
486 run_test 17c "symlinks: open dangling (should return error)"
487
488 test_17d() {
489         test_mkdir $DIR/$tdir
490         ln -s foo $DIR/$tdir/$tfile
491         touch $DIR/$tdir/$tfile || error "creating to new symlink"
492 }
493 run_test 17d "symlinks: create dangling"
494
495 test_17e() {
496         test_mkdir $DIR/$tdir
497         local foo=$DIR/$tdir/$tfile
498         ln -s $foo $foo || error "create symlink failed"
499         ls -l $foo || error "ls -l failed"
500         ls $foo && error "ls not failed" || true
501 }
502 run_test 17e "symlinks: create recursive symlink (should return error)"
503
504 test_17f() {
505         test_mkdir $DIR/$tdir
506         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
507         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
508         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
509         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
510         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
511         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
512         ls -l  $DIR/$tdir
513 }
514 run_test 17f "symlinks: long and very long symlink name"
515
516 # str_repeat(S, N) generate a string that is string S repeated N times
517 str_repeat() {
518         local s=$1
519         local n=$2
520         local ret=''
521         while [ $((n -= 1)) -ge 0 ]; do
522                 ret=$ret$s
523         done
524         echo $ret
525 }
526
527 # Long symlinks and LU-2241
528 test_17g() {
529         test_mkdir $DIR/$tdir
530         local TESTS="59 60 61 4094 4095"
531
532         # Fix for inode size boundary in 2.1.4
533         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
534                 TESTS="4094 4095"
535
536         # Patch not applied to 2.2 or 2.3 branches
537         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
538         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
539                 TESTS="4094 4095"
540
541         # skip long symlink name for rhel6.5.
542         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
543         grep -q '6.5' /etc/redhat-release &>/dev/null &&
544                 TESTS="59 60 61 4062 4063"
545
546         for i in $TESTS; do
547                 local SYMNAME=$(str_repeat 'x' $i)
548                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
549                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
550         done
551 }
552 run_test 17g "symlinks: really long symlink name and inode boundaries"
553
554 test_17h() { #bug 17378
555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
556         remote_mds_nodsh && skip "remote MDS with nodsh"
557
558         local mdt_idx
559
560         test_mkdir $DIR/$tdir
561         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
562         $LFS setstripe -c -1 $DIR/$tdir
563         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
564         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
565         touch $DIR/$tdir/$tfile || true
566 }
567 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
568
569 test_17i() { #bug 20018
570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
571         remote_mds_nodsh && skip "remote MDS with nodsh"
572
573         local foo=$DIR/$tdir/$tfile
574         local mdt_idx
575
576         test_mkdir -c1 $DIR/$tdir
577         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
578         ln -s $foo $foo || error "create symlink failed"
579 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
580         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
581         ls -l $foo && error "error not detected"
582         return 0
583 }
584 run_test 17i "don't panic on short symlink (should return error)"
585
586 test_17k() { #bug 22301
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         [[ -z "$(which rsync 2>/dev/null)" ]] &&
589                 skip "no rsync command"
590         rsync --help | grep -q xattr ||
591                 skip_env "$(rsync --version | head -n1) does not support xattrs"
592         test_mkdir $DIR/$tdir
593         test_mkdir $DIR/$tdir.new
594         touch $DIR/$tdir/$tfile
595         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
596         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
597                 error "rsync failed with xattrs enabled"
598 }
599 run_test 17k "symlinks: rsync with xattrs enabled"
600
601 test_17l() { # LU-279
602         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
603                 skip "no getfattr command"
604
605         test_mkdir $DIR/$tdir
606         touch $DIR/$tdir/$tfile
607         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
608         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
609                 # -h to not follow symlinks. -m '' to list all the xattrs.
610                 # grep to remove first line: '# file: $path'.
611                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
612                 do
613                         lgetxattr_size_check $path $xattr ||
614                                 error "lgetxattr_size_check $path $xattr failed"
615                 done
616         done
617 }
618 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
619
620 # LU-1540
621 test_17m() {
622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
623         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
624         remote_mds_nodsh && skip "remote MDS with nodsh"
625         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
626         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
627                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
628
629         local short_sym="0123456789"
630         local wdir=$DIR/$tdir
631         local i
632
633         test_mkdir $wdir
634         long_sym=$short_sym
635         # create a long symlink file
636         for ((i = 0; i < 4; ++i)); do
637                 long_sym=${long_sym}${long_sym}
638         done
639
640         echo "create 512 short and long symlink files under $wdir"
641         for ((i = 0; i < 256; ++i)); do
642                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
643                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
644         done
645
646         echo "erase them"
647         rm -f $wdir/*
648         sync
649         wait_delete_completed
650
651         echo "recreate the 512 symlink files with a shorter string"
652         for ((i = 0; i < 512; ++i)); do
653                 # rewrite the symlink file with a shorter string
654                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
655                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
656         done
657
658         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
659         local devname=$(mdsdevname $mds_index)
660
661         echo "stop and checking mds${mds_index}:"
662         # e2fsck should not return error
663         stop mds${mds_index}
664         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
665         rc=$?
666
667         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
668                 error "start mds${mds_index} failed"
669         df $MOUNT > /dev/null 2>&1
670         [ $rc -eq 0 ] ||
671                 error "e2fsck detected error for short/long symlink: rc=$rc"
672         rm -f $wdir/*
673 }
674 run_test 17m "run e2fsck against MDT which contains short/long symlink"
675
676 check_fs_consistency_17n() {
677         local mdt_index
678         local rc=0
679
680         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
681         # so it only check MDT1/MDT2 instead of all of MDTs.
682         for mdt_index in 1 2; do
683                 local devname=$(mdsdevname $mdt_index)
684                 # e2fsck should not return error
685                 stop mds${mdt_index}
686                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
687                         rc=$((rc + $?))
688
689                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
690                         error "mount mds$mdt_index failed"
691                 df $MOUNT > /dev/null 2>&1
692         done
693         return $rc
694 }
695
696 test_17n() {
697         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
699         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
700         remote_mds_nodsh && skip "remote MDS with nodsh"
701         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
702         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
703                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
704
705         local i
706
707         test_mkdir $DIR/$tdir
708         for ((i=0; i<10; i++)); do
709                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
710                         error "create remote dir error $i"
711                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
712                         error "create files under remote dir failed $i"
713         done
714
715         check_fs_consistency_17n ||
716                 error "e2fsck report error after create files under remote dir"
717
718         for ((i = 0; i < 10; i++)); do
719                 rm -rf $DIR/$tdir/remote_dir_${i} ||
720                         error "destroy remote dir error $i"
721         done
722
723         check_fs_consistency_17n ||
724                 error "e2fsck report error after unlink files under remote dir"
725
726         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
727                 skip "lustre < 2.4.50 does not support migrate mv"
728
729         for ((i = 0; i < 10; i++)); do
730                 mkdir -p $DIR/$tdir/remote_dir_${i}
731                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
732                         error "create files under remote dir failed $i"
733                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
734                         error "migrate remote dir error $i"
735         done
736         check_fs_consistency_17n || error "e2fsck report error after migration"
737
738         for ((i = 0; i < 10; i++)); do
739                 rm -rf $DIR/$tdir/remote_dir_${i} ||
740                         error "destroy remote dir error $i"
741         done
742
743         check_fs_consistency_17n || error "e2fsck report error after unlink"
744 }
745 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
746
747 test_17o() {
748         remote_mds_nodsh && skip "remote MDS with nodsh"
749         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
750                 skip "Need MDS version at least 2.3.64"
751
752         local wdir=$DIR/${tdir}o
753         local mdt_index
754         local rc=0
755
756         test_mkdir $wdir
757         touch $wdir/$tfile
758         mdt_index=$($LFS getstripe -m $wdir/$tfile)
759         mdt_index=$((mdt_index + 1))
760
761         cancel_lru_locks mdc
762         #fail mds will wait the failover finish then set
763         #following fail_loc to avoid interfer the recovery process.
764         fail mds${mdt_index}
765
766         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
767         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
768         ls -l $wdir/$tfile && rc=1
769         do_facet mds${mdt_index} lctl set_param fail_loc=0
770         [[ $rc -eq 0 ]] || error "stat file should fail"
771 }
772 run_test 17o "stat file with incompat LMA feature"
773
774 test_18() {
775         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
776         ls $DIR || error "Failed to ls $DIR: $?"
777 }
778 run_test 18 "touch .../f ; ls ... =============================="
779
780 test_19a() {
781         touch $DIR/$tfile
782         ls -l $DIR
783         rm $DIR/$tfile
784         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
785 }
786 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
787
788 test_19b() {
789         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
790 }
791 run_test 19b "ls -l .../f19 (should return error) =============="
792
793 test_19c() {
794         [ $RUNAS_ID -eq $UID ] &&
795                 skip_env "RUNAS_ID = UID = $UID -- skipping"
796
797         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
798 }
799 run_test 19c "$RUNAS touch .../f19 (should return error) =="
800
801 test_19d() {
802         cat $DIR/f19 && error || true
803 }
804 run_test 19d "cat .../f19 (should return error) =============="
805
806 test_20() {
807         touch $DIR/$tfile
808         rm $DIR/$tfile
809         touch $DIR/$tfile
810         rm $DIR/$tfile
811         touch $DIR/$tfile
812         rm $DIR/$tfile
813         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
814 }
815 run_test 20 "touch .../f ; ls -l ..."
816
817 test_21() {
818         test_mkdir $DIR/$tdir
819         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
820         ln -s dangle $DIR/$tdir/link
821         echo foo >> $DIR/$tdir/link
822         cat $DIR/$tdir/dangle
823         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
824         $CHECKSTAT -f -t file $DIR/$tdir/link ||
825                 error "$tdir/link not linked to a file"
826 }
827 run_test 21 "write to dangling link"
828
829 test_22() {
830         local wdir=$DIR/$tdir
831         test_mkdir $wdir
832         chown $RUNAS_ID:$RUNAS_GID $wdir
833         (cd $wdir || error "cd $wdir failed";
834                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
835                 $RUNAS tar xf -)
836         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
837         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
838         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
839                 error "checkstat -u failed"
840 }
841 run_test 22 "unpack tar archive as non-root user"
842
843 # was test_23
844 test_23a() {
845         test_mkdir $DIR/$tdir
846         local file=$DIR/$tdir/$tfile
847
848         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
849         openfile -f O_CREAT:O_EXCL $file &&
850                 error "$file recreate succeeded" || true
851 }
852 run_test 23a "O_CREAT|O_EXCL in subdir"
853
854 test_23b() { # bug 18988
855         test_mkdir $DIR/$tdir
856         local file=$DIR/$tdir/$tfile
857
858         rm -f $file
859         echo foo > $file || error "write filed"
860         echo bar >> $file || error "append filed"
861         $CHECKSTAT -s 8 $file || error "wrong size"
862         rm $file
863 }
864 run_test 23b "O_APPEND check"
865
866 # LU-9409, size with O_APPEND and tiny writes
867 test_23c() {
868         local file=$DIR/$tfile
869
870         # single dd
871         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
872         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
873         rm -f $file
874
875         # racing tiny writes
876         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
877         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
878         wait
879         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
880         rm -f $file
881
882         #racing tiny & normal writes
883         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
884         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
885         wait
886         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
887         rm -f $file
888
889         #racing tiny & normal writes 2, ugly numbers
890         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
891         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
892         wait
893         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
894         rm -f $file
895 }
896 run_test 23c "O_APPEND size checks for tiny writes"
897
898 # LU-11069 file offset is correct after appending writes
899 test_23d() {
900         local file=$DIR/$tfile
901         local offset
902
903         echo CentaurHauls > $file
904         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
905         if ((offset != 26)); then
906                 error "wrong offset, expected 26, got '$offset'"
907         fi
908 }
909 run_test 23d "file offset is correct after appending writes"
910
911 # rename sanity
912 test_24a() {
913         echo '-- same directory rename'
914         test_mkdir $DIR/$tdir
915         touch $DIR/$tdir/$tfile.1
916         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
917         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
918 }
919 run_test 24a "rename file to non-existent target"
920
921 test_24b() {
922         test_mkdir $DIR/$tdir
923         touch $DIR/$tdir/$tfile.{1,2}
924         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
925         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
926         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
927 }
928 run_test 24b "rename file to existing target"
929
930 test_24c() {
931         test_mkdir $DIR/$tdir
932         test_mkdir $DIR/$tdir/d$testnum.1
933         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
934         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
935         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
936 }
937 run_test 24c "rename directory to non-existent target"
938
939 test_24d() {
940         test_mkdir -c1 $DIR/$tdir
941         test_mkdir -c1 $DIR/$tdir/d$testnum.1
942         test_mkdir -c1 $DIR/$tdir/d$testnum.2
943         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
944         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
945         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
946 }
947 run_test 24d "rename directory to existing target"
948
949 test_24e() {
950         echo '-- cross directory renames --'
951         test_mkdir $DIR/R5a
952         test_mkdir $DIR/R5b
953         touch $DIR/R5a/f
954         mv $DIR/R5a/f $DIR/R5b/g
955         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
956         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
957 }
958 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
959
960 test_24f() {
961         test_mkdir $DIR/R6a
962         test_mkdir $DIR/R6b
963         touch $DIR/R6a/f $DIR/R6b/g
964         mv $DIR/R6a/f $DIR/R6b/g
965         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
966         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
967 }
968 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
969
970 test_24g() {
971         test_mkdir $DIR/R7a
972         test_mkdir $DIR/R7b
973         test_mkdir $DIR/R7a/d
974         mv $DIR/R7a/d $DIR/R7b/e
975         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
976         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
977 }
978 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
979
980 test_24h() {
981         test_mkdir -c1 $DIR/R8a
982         test_mkdir -c1 $DIR/R8b
983         test_mkdir -c1 $DIR/R8a/d
984         test_mkdir -c1 $DIR/R8b/e
985         mrename $DIR/R8a/d $DIR/R8b/e
986         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
987         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
988 }
989 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
990
991 test_24i() {
992         echo "-- rename error cases"
993         test_mkdir $DIR/R9
994         test_mkdir $DIR/R9/a
995         touch $DIR/R9/f
996         mrename $DIR/R9/f $DIR/R9/a
997         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
998         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
999         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1000 }
1001 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1002
1003 test_24j() {
1004         test_mkdir $DIR/R10
1005         mrename $DIR/R10/f $DIR/R10/g
1006         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1007         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1008         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1009 }
1010 run_test 24j "source does not exist ============================"
1011
1012 test_24k() {
1013         test_mkdir $DIR/R11a
1014         test_mkdir $DIR/R11a/d
1015         touch $DIR/R11a/f
1016         mv $DIR/R11a/f $DIR/R11a/d
1017         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1018         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1019 }
1020 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1021
1022 # bug 2429 - rename foo foo foo creates invalid file
1023 test_24l() {
1024         f="$DIR/f24l"
1025         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1026 }
1027 run_test 24l "Renaming a file to itself ========================"
1028
1029 test_24m() {
1030         f="$DIR/f24m"
1031         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1032         # on ext3 this does not remove either the source or target files
1033         # though the "expected" operation would be to remove the source
1034         $CHECKSTAT -t file ${f} || error "${f} missing"
1035         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1036 }
1037 run_test 24m "Renaming a file to a hard link to itself ========="
1038
1039 test_24n() {
1040     f="$DIR/f24n"
1041     # this stats the old file after it was renamed, so it should fail
1042     touch ${f}
1043     $CHECKSTAT ${f} || error "${f} missing"
1044     mv ${f} ${f}.rename
1045     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1046     $CHECKSTAT -a ${f} || error "${f} exists"
1047 }
1048 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1049
1050 test_24o() {
1051         test_mkdir $DIR/$tdir
1052         rename_many -s random -v -n 10 $DIR/$tdir
1053 }
1054 run_test 24o "rename of files during htree split"
1055
1056 test_24p() {
1057         test_mkdir $DIR/R12a
1058         test_mkdir $DIR/R12b
1059         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1060         mrename $DIR/R12a $DIR/R12b
1061         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1062         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1063         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1064         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1065 }
1066 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1067
1068 cleanup_multiop_pause() {
1069         trap 0
1070         kill -USR1 $MULTIPID
1071 }
1072
1073 test_24q() {
1074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1075
1076         test_mkdir $DIR/R13a
1077         test_mkdir $DIR/R13b
1078         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1079         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1080         MULTIPID=$!
1081
1082         trap cleanup_multiop_pause EXIT
1083         mrename $DIR/R13a $DIR/R13b
1084         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1085         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1086         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1087         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1088         cleanup_multiop_pause
1089         wait $MULTIPID || error "multiop close failed"
1090 }
1091 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1092
1093 test_24r() { #bug 3789
1094         test_mkdir $DIR/R14a
1095         test_mkdir $DIR/R14a/b
1096         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1097         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1098         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1099 }
1100 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1101
1102 test_24s() {
1103         test_mkdir $DIR/R15a
1104         test_mkdir $DIR/R15a/b
1105         test_mkdir $DIR/R15a/b/c
1106         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1107         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1108         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1109 }
1110 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1111 test_24t() {
1112         test_mkdir $DIR/R16a
1113         test_mkdir $DIR/R16a/b
1114         test_mkdir $DIR/R16a/b/c
1115         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1116         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1117         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1118 }
1119 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1120
1121 test_24u() { # bug12192
1122         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1123         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1124 }
1125 run_test 24u "create stripe file"
1126
1127 simple_cleanup_common() {
1128         local rc=0
1129         trap 0
1130         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1131
1132         local start=$SECONDS
1133         rm -rf $DIR/$tdir
1134         rc=$?
1135         wait_delete_completed
1136         echo "cleanup time $((SECONDS - start))"
1137         return $rc
1138 }
1139
1140 max_pages_per_rpc() {
1141         local mdtname="$(printf "MDT%04x" ${1:-0})"
1142         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1143 }
1144
1145 test_24v() {
1146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1147
1148         local nrfiles=${COUNT:-100000}
1149         local fname="$DIR/$tdir/$tfile"
1150
1151         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1152         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1153
1154         test_mkdir "$(dirname $fname)"
1155         # assume MDT0000 has the fewest inodes
1156         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1157         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1158         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1159
1160         trap simple_cleanup_common EXIT
1161
1162         createmany -m "$fname" $nrfiles
1163
1164         cancel_lru_locks mdc
1165         lctl set_param mdc.*.stats clear
1166
1167         # was previously test_24D: LU-6101
1168         # readdir() returns correct number of entries after cursor reload
1169         local num_ls=$(ls $DIR/$tdir | wc -l)
1170         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1171         local num_all=$(ls -a $DIR/$tdir | wc -l)
1172         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1173                 [ $num_all -ne $((nrfiles + 2)) ]; then
1174                         error "Expected $nrfiles files, got $num_ls " \
1175                                 "($num_uniq unique $num_all .&..)"
1176         fi
1177         # LU-5 large readdir
1178         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1179         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1180         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1181         # take into account of overhead in lu_dirpage header and end mark in
1182         # each page, plus one in rpc_num calculation.
1183         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1184         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1185         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1186         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1187         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1188         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1189         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1190         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1191                 error "large readdir doesn't take effect: " \
1192                       "$mds_readpage should be about $rpc_max"
1193
1194         simple_cleanup_common
1195 }
1196 run_test 24v "list large directory (test hash collision, b=17560)"
1197
1198 test_24w() { # bug21506
1199         SZ1=234852
1200         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1201         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1202         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1203         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1204         [[ "$SZ1" -eq "$SZ2" ]] ||
1205                 error "Error reading at the end of the file $tfile"
1206 }
1207 run_test 24w "Reading a file larger than 4Gb"
1208
1209 test_24x() {
1210         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1212         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1213                 skip "Need MDS version at least 2.7.56"
1214
1215         local MDTIDX=1
1216         local remote_dir=$DIR/$tdir/remote_dir
1217
1218         test_mkdir $DIR/$tdir
1219         $LFS mkdir -i $MDTIDX $remote_dir ||
1220                 error "create remote directory failed"
1221
1222         test_mkdir $DIR/$tdir/src_dir
1223         touch $DIR/$tdir/src_file
1224         test_mkdir $remote_dir/tgt_dir
1225         touch $remote_dir/tgt_file
1226
1227         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1228                 error "rename dir cross MDT failed!"
1229
1230         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1231                 error "rename file cross MDT failed!"
1232
1233         touch $DIR/$tdir/ln_file
1234         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1235                 error "ln file cross MDT failed"
1236
1237         rm -rf $DIR/$tdir || error "Can not delete directories"
1238 }
1239 run_test 24x "cross MDT rename/link"
1240
1241 test_24y() {
1242         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1244
1245         local remote_dir=$DIR/$tdir/remote_dir
1246         local mdtidx=1
1247
1248         test_mkdir $DIR/$tdir
1249         $LFS mkdir -i $mdtidx $remote_dir ||
1250                 error "create remote directory failed"
1251
1252         test_mkdir $remote_dir/src_dir
1253         touch $remote_dir/src_file
1254         test_mkdir $remote_dir/tgt_dir
1255         touch $remote_dir/tgt_file
1256
1257         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1258                 error "rename subdir in the same remote dir failed!"
1259
1260         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1261                 error "rename files in the same remote dir failed!"
1262
1263         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1264                 error "link files in the same remote dir failed!"
1265
1266         rm -rf $DIR/$tdir || error "Can not delete directories"
1267 }
1268 run_test 24y "rename/link on the same dir should succeed"
1269
1270 test_24z() {
1271         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1272         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1273                 skip "Need MDS version at least 2.12.51"
1274
1275         local index
1276
1277         for index in 0 1; do
1278                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1279                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1280         done
1281
1282         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1283
1284         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1285         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1286
1287         local mdts=$(comma_list $(mdts_nodes))
1288
1289         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1290         stack_trap "do_nodes $mdts $LCTL \
1291                 set_param mdt.*.enable_remote_rename=1" EXIT
1292
1293         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1294
1295         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1296         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1297 }
1298 run_test 24z "cross-MDT rename is done as cp"
1299
1300 test_24A() { # LU-3182
1301         local NFILES=5000
1302
1303         rm -rf $DIR/$tdir
1304         test_mkdir $DIR/$tdir
1305         trap simple_cleanup_common EXIT
1306         createmany -m $DIR/$tdir/$tfile $NFILES
1307         local t=$(ls $DIR/$tdir | wc -l)
1308         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1309         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1310         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1311            [ $v -ne $((NFILES + 2)) ] ; then
1312                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1313         fi
1314
1315         simple_cleanup_common || error "Can not delete directories"
1316 }
1317 run_test 24A "readdir() returns correct number of entries."
1318
1319 test_24B() { # LU-4805
1320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1321
1322         local count
1323
1324         test_mkdir $DIR/$tdir
1325         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1326                 error "create striped dir failed"
1327
1328         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1329         [ $count -eq 2 ] || error "Expected 2, got $count"
1330
1331         touch $DIR/$tdir/striped_dir/a
1332
1333         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1334         [ $count -eq 3 ] || error "Expected 3, got $count"
1335
1336         touch $DIR/$tdir/striped_dir/.f
1337
1338         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1339         [ $count -eq 4 ] || error "Expected 4, got $count"
1340
1341         rm -rf $DIR/$tdir || error "Can not delete directories"
1342 }
1343 run_test 24B "readdir for striped dir return correct number of entries"
1344
1345 test_24C() {
1346         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1347
1348         mkdir $DIR/$tdir
1349         mkdir $DIR/$tdir/d0
1350         mkdir $DIR/$tdir/d1
1351
1352         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1353                 error "create striped dir failed"
1354
1355         cd $DIR/$tdir/d0/striped_dir
1356
1357         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1358         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1359         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1360
1361         [ "$d0_ino" = "$parent_ino" ] ||
1362                 error ".. wrong, expect $d0_ino, get $parent_ino"
1363
1364         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1365                 error "mv striped dir failed"
1366
1367         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1368
1369         [ "$d1_ino" = "$parent_ino" ] ||
1370                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1371 }
1372 run_test 24C "check .. in striped dir"
1373
1374 test_24E() {
1375         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1377
1378         mkdir -p $DIR/$tdir
1379         mkdir $DIR/$tdir/src_dir
1380         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1381                 error "create remote source failed"
1382
1383         touch $DIR/$tdir/src_dir/src_child/a
1384
1385         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1386                 error "create remote target dir failed"
1387
1388         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1389                 error "create remote target child failed"
1390
1391         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1392                 error "rename dir cross MDT failed!"
1393
1394         find $DIR/$tdir
1395
1396         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1397                 error "src_child still exists after rename"
1398
1399         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1400                 error "missing file(a) after rename"
1401
1402         rm -rf $DIR/$tdir || error "Can not delete directories"
1403 }
1404 run_test 24E "cross MDT rename/link"
1405
1406 test_24F () {
1407         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1408
1409         local repeats=1000
1410         [ "$SLOW" = "no" ] && repeats=100
1411
1412         mkdir -p $DIR/$tdir
1413
1414         echo "$repeats repeats"
1415         for ((i = 0; i < repeats; i++)); do
1416                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1417                 touch $DIR/$tdir/test/a || error "touch fails"
1418                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1419                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1420         done
1421
1422         true
1423 }
1424 run_test 24F "hash order vs readdir (LU-11330)"
1425
1426 test_25a() {
1427         echo '== symlink sanity ============================================='
1428
1429         test_mkdir $DIR/d25
1430         ln -s d25 $DIR/s25
1431         touch $DIR/s25/foo ||
1432                 error "File creation in symlinked directory failed"
1433 }
1434 run_test 25a "create file in symlinked directory ==============="
1435
1436 test_25b() {
1437         [ ! -d $DIR/d25 ] && test_25a
1438         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1439 }
1440 run_test 25b "lookup file in symlinked directory ==============="
1441
1442 test_26a() {
1443         test_mkdir $DIR/d26
1444         test_mkdir $DIR/d26/d26-2
1445         ln -s d26/d26-2 $DIR/s26
1446         touch $DIR/s26/foo || error "File creation failed"
1447 }
1448 run_test 26a "multiple component symlink ======================="
1449
1450 test_26b() {
1451         test_mkdir -p $DIR/$tdir/d26-2
1452         ln -s $tdir/d26-2/foo $DIR/s26-2
1453         touch $DIR/s26-2 || error "File creation failed"
1454 }
1455 run_test 26b "multiple component symlink at end of lookup ======"
1456
1457 test_26c() {
1458         test_mkdir $DIR/d26.2
1459         touch $DIR/d26.2/foo
1460         ln -s d26.2 $DIR/s26.2-1
1461         ln -s s26.2-1 $DIR/s26.2-2
1462         ln -s s26.2-2 $DIR/s26.2-3
1463         chmod 0666 $DIR/s26.2-3/foo
1464 }
1465 run_test 26c "chain of symlinks"
1466
1467 # recursive symlinks (bug 439)
1468 test_26d() {
1469         ln -s d26-3/foo $DIR/d26-3
1470 }
1471 run_test 26d "create multiple component recursive symlink"
1472
1473 test_26e() {
1474         [ ! -h $DIR/d26-3 ] && test_26d
1475         rm $DIR/d26-3
1476 }
1477 run_test 26e "unlink multiple component recursive symlink"
1478
1479 # recursive symlinks (bug 7022)
1480 test_26f() {
1481         test_mkdir $DIR/$tdir
1482         test_mkdir $DIR/$tdir/$tfile
1483         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1484         test_mkdir -p lndir/bar1
1485         test_mkdir $DIR/$tdir/$tfile/$tfile
1486         cd $tfile                || error "cd $tfile failed"
1487         ln -s .. dotdot          || error "ln dotdot failed"
1488         ln -s dotdot/lndir lndir || error "ln lndir failed"
1489         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1490         output=`ls $tfile/$tfile/lndir/bar1`
1491         [ "$output" = bar1 ] && error "unexpected output"
1492         rm -r $tfile             || error "rm $tfile failed"
1493         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1494 }
1495 run_test 26f "rm -r of a directory which has recursive symlink"
1496
1497 test_27a() {
1498         test_mkdir $DIR/$tdir
1499         $LFS getstripe $DIR/$tdir
1500         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1501         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1502         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1503 }
1504 run_test 27a "one stripe file"
1505
1506 test_27b() {
1507         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1508
1509         test_mkdir $DIR/$tdir
1510         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1511         $LFS getstripe -c $DIR/$tdir/$tfile
1512         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1513                 error "two-stripe file doesn't have two stripes"
1514
1515         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1516 }
1517 run_test 27b "create and write to two stripe file"
1518
1519 # 27c family tests specific striping, setstripe -o
1520 test_27ca() {
1521         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1522         test_mkdir -p $DIR/$tdir
1523         local osts="1"
1524
1525         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1526         $LFS getstripe -i $DIR/$tdir/$tfile
1527         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1528                 error "stripe not on specified OST"
1529
1530         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1531 }
1532 run_test 27ca "one stripe on specified OST"
1533
1534 test_27cb() {
1535         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1536         test_mkdir -p $DIR/$tdir
1537         local osts="1,0"
1538         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1539         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1540         echo "$getstripe"
1541
1542         # Strip getstripe output to a space separated list of OSTs
1543         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1544                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1545         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1546                 error "stripes not on specified OSTs"
1547
1548         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1549 }
1550 run_test 27cb "two stripes on specified OSTs"
1551
1552 test_27cc() {
1553         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1554         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1555                 skip "server does not support overstriping"
1556
1557         test_mkdir -p $DIR/$tdir
1558         local osts="0,0"
1559         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1560         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1561         echo "$getstripe"
1562
1563         # Strip getstripe output to a space separated list of OSTs
1564         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1565                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1566         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1567                 error "stripes not on specified OSTs"
1568
1569         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1570 }
1571 run_test 27cc "two stripes on the same OST"
1572
1573 test_27cd() {
1574         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1575         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1576                 skip "server does not support overstriping"
1577         test_mkdir -p $DIR/$tdir
1578         local osts="0,1,1,0"
1579         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1580         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1581         echo "$getstripe"
1582
1583         # Strip getstripe output to a space separated list of OSTs
1584         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1585                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1586         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1587                 error "stripes not on specified OSTs"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1590 }
1591 run_test 27cd "four stripes on two OSTs"
1592
1593 test_27ce() {
1594         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1595                 skip_env "too many osts, skipping"
1596         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1597                 skip "server does not support overstriping"
1598         # We do one more stripe than we have OSTs
1599         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1600                 skip_env "ea_inode feature disabled"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts=""
1604         for i in $(seq 0 $OSTCOUNT);
1605         do
1606                 osts=$osts"0"
1607                 if [ $i -ne $OSTCOUNT ]; then
1608                         osts=$osts","
1609                 fi
1610         done
1611         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1612         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1613         echo "$getstripe"
1614
1615         # Strip getstripe output to a space separated list of OSTs
1616         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1617                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1618         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1619                 error "stripes not on specified OSTs"
1620
1621         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1622 }
1623 run_test 27ce "more stripes than OSTs with -o"
1624
1625 test_27d() {
1626         test_mkdir $DIR/$tdir
1627         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1628                 error "setstripe failed"
1629         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1630         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1631 }
1632 run_test 27d "create file with default settings"
1633
1634 test_27e() {
1635         # LU-5839 adds check for existed layout before setting it
1636         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1637                 skip "Need MDS version at least 2.7.56"
1638
1639         test_mkdir $DIR/$tdir
1640         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1641         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1642         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1643 }
1644 run_test 27e "setstripe existing file (should return error)"
1645
1646 test_27f() {
1647         test_mkdir $DIR/$tdir
1648         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1649                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1650         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1651                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1652         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1653         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1654 }
1655 run_test 27f "setstripe with bad stripe size (should return error)"
1656
1657 test_27g() {
1658         test_mkdir $DIR/$tdir
1659         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1660         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1661                 error "$DIR/$tdir/$tfile has object"
1662 }
1663 run_test 27g "$LFS getstripe with no objects"
1664
1665 test_27ga() {
1666         test_mkdir $DIR/$tdir
1667         touch $DIR/$tdir/$tfile || error "touch failed"
1668         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1669         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1670         local rc=$?
1671         (( rc == 2 )) || error "getstripe did not return ENOENT"
1672 }
1673 run_test 27ga "$LFS getstripe with missing file (should return error)"
1674
1675 test_27i() {
1676         test_mkdir $DIR/$tdir
1677         touch $DIR/$tdir/$tfile || error "touch failed"
1678         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1679                 error "missing objects"
1680 }
1681 run_test 27i "$LFS getstripe with some objects"
1682
1683 test_27j() {
1684         test_mkdir $DIR/$tdir
1685         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1686                 error "setstripe failed" || true
1687 }
1688 run_test 27j "setstripe with bad stripe offset (should return error)"
1689
1690 test_27k() { # bug 2844
1691         test_mkdir $DIR/$tdir
1692         local file=$DIR/$tdir/$tfile
1693         local ll_max_blksize=$((4 * 1024 * 1024))
1694         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1695         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1696         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1697         dd if=/dev/zero of=$file bs=4k count=1
1698         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1699         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1700 }
1701 run_test 27k "limit i_blksize for broken user apps"
1702
1703 test_27l() {
1704         mcreate $DIR/$tfile || error "creating file"
1705         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1706                 error "setstripe should have failed" || true
1707 }
1708 run_test 27l "check setstripe permissions (should return error)"
1709
1710 test_27m() {
1711         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1712
1713         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1714                 skip_env "multiple clients -- skipping"
1715
1716         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1717                    head -n1)
1718         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1719                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1720         fi
1721         trap simple_cleanup_common EXIT
1722         test_mkdir $DIR/$tdir
1723         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1724         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1725                 error "dd should fill OST0"
1726         i=2
1727         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1728                 i=$((i + 1))
1729                 [ $i -gt 256 ] && break
1730         done
1731         i=$((i + 1))
1732         touch $DIR/$tdir/$tfile.$i
1733         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1734             awk '{print $1}'| grep -w "0") ] &&
1735                 error "OST0 was full but new created file still use it"
1736         i=$((i + 1))
1737         touch $DIR/$tdir/$tfile.$i
1738         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1739             awk '{print $1}'| grep -w "0") ] &&
1740                 error "OST0 was full but new created file still use it"
1741         simple_cleanup_common
1742 }
1743 run_test 27m "create file while OST0 was full"
1744
1745 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1746 # if the OST isn't full anymore.
1747 reset_enospc() {
1748         local OSTIDX=${1:-""}
1749
1750         local list=$(comma_list $(osts_nodes))
1751         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1752
1753         do_nodes $list lctl set_param fail_loc=0
1754         sync    # initiate all OST_DESTROYs from MDS to OST
1755         sleep_maxage
1756 }
1757
1758 exhaust_precreations() {
1759         local OSTIDX=$1
1760         local FAILLOC=$2
1761         local FAILIDX=${3:-$OSTIDX}
1762         local ofacet=ost$((OSTIDX + 1))
1763
1764         test_mkdir -p -c1 $DIR/$tdir
1765         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1766         local mfacet=mds$((mdtidx + 1))
1767         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1768
1769         local OST=$(ostname_from_index $OSTIDX)
1770
1771         # on the mdt's osc
1772         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1773         local last_id=$(do_facet $mfacet lctl get_param -n \
1774                         osp.$mdtosc_proc1.prealloc_last_id)
1775         local next_id=$(do_facet $mfacet lctl get_param -n \
1776                         osp.$mdtosc_proc1.prealloc_next_id)
1777
1778         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1779         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1780
1781         test_mkdir -p $DIR/$tdir/${OST}
1782         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1783 #define OBD_FAIL_OST_ENOSPC              0x215
1784         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1785         echo "Creating to objid $last_id on ost $OST..."
1786         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1787         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1788         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1789         sleep_maxage
1790 }
1791
1792 exhaust_all_precreations() {
1793         local i
1794         for (( i=0; i < OSTCOUNT; i++ )) ; do
1795                 exhaust_precreations $i $1 -1
1796         done
1797 }
1798
1799 test_27n() {
1800         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1802         remote_mds_nodsh && skip "remote MDS with nodsh"
1803         remote_ost_nodsh && skip "remote OST with nodsh"
1804
1805         reset_enospc
1806         rm -f $DIR/$tdir/$tfile
1807         exhaust_precreations 0 0x80000215
1808         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1809         touch $DIR/$tdir/$tfile || error "touch failed"
1810         $LFS getstripe $DIR/$tdir/$tfile
1811         reset_enospc
1812 }
1813 run_test 27n "create file with some full OSTs"
1814
1815 test_27o() {
1816         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1818         remote_mds_nodsh && skip "remote MDS with nodsh"
1819         remote_ost_nodsh && skip "remote OST with nodsh"
1820
1821         reset_enospc
1822         rm -f $DIR/$tdir/$tfile
1823         exhaust_all_precreations 0x215
1824
1825         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1826
1827         reset_enospc
1828         rm -rf $DIR/$tdir/*
1829 }
1830 run_test 27o "create file with all full OSTs (should error)"
1831
1832 test_27p() {
1833         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1835         remote_mds_nodsh && skip "remote MDS with nodsh"
1836         remote_ost_nodsh && skip "remote OST with nodsh"
1837
1838         reset_enospc
1839         rm -f $DIR/$tdir/$tfile
1840         test_mkdir $DIR/$tdir
1841
1842         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1843         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1844         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1845
1846         exhaust_precreations 0 0x80000215
1847         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1848         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1849         $LFS getstripe $DIR/$tdir/$tfile
1850
1851         reset_enospc
1852 }
1853 run_test 27p "append to a truncated file with some full OSTs"
1854
1855 test_27q() {
1856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1858         remote_mds_nodsh && skip "remote MDS with nodsh"
1859         remote_ost_nodsh && skip "remote OST with nodsh"
1860
1861         reset_enospc
1862         rm -f $DIR/$tdir/$tfile
1863
1864         test_mkdir $DIR/$tdir
1865         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1866         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1867                 error "truncate $DIR/$tdir/$tfile failed"
1868         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1869
1870         exhaust_all_precreations 0x215
1871
1872         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1873         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1874
1875         reset_enospc
1876 }
1877 run_test 27q "append to truncated file with all OSTs full (should error)"
1878
1879 test_27r() {
1880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1882         remote_mds_nodsh && skip "remote MDS with nodsh"
1883         remote_ost_nodsh && skip "remote OST with nodsh"
1884
1885         reset_enospc
1886         rm -f $DIR/$tdir/$tfile
1887         exhaust_precreations 0 0x80000215
1888
1889         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1890
1891         reset_enospc
1892 }
1893 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1894
1895 test_27s() { # bug 10725
1896         test_mkdir $DIR/$tdir
1897         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1898         local stripe_count=0
1899         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1900         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1901                 error "stripe width >= 2^32 succeeded" || true
1902
1903 }
1904 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1905
1906 test_27t() { # bug 10864
1907         WDIR=$(pwd)
1908         WLFS=$(which lfs)
1909         cd $DIR
1910         touch $tfile
1911         $WLFS getstripe $tfile
1912         cd $WDIR
1913 }
1914 run_test 27t "check that utils parse path correctly"
1915
1916 test_27u() { # bug 4900
1917         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1918         remote_mds_nodsh && skip "remote MDS with nodsh"
1919
1920         local index
1921         local list=$(comma_list $(mdts_nodes))
1922
1923 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1924         do_nodes $list $LCTL set_param fail_loc=0x139
1925         test_mkdir -p $DIR/$tdir
1926         trap simple_cleanup_common EXIT
1927         createmany -o $DIR/$tdir/t- 1000
1928         do_nodes $list $LCTL set_param fail_loc=0
1929
1930         TLOG=$TMP/$tfile.getstripe
1931         $LFS getstripe $DIR/$tdir > $TLOG
1932         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1933         unlinkmany $DIR/$tdir/t- 1000
1934         trap 0
1935         [[ $OBJS -gt 0 ]] &&
1936                 error "$OBJS objects created on OST-0. See $TLOG" ||
1937                 rm -f $TLOG
1938 }
1939 run_test 27u "skip object creation on OSC w/o objects"
1940
1941 test_27v() { # bug 4900
1942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1944         remote_mds_nodsh && skip "remote MDS with nodsh"
1945         remote_ost_nodsh && skip "remote OST with nodsh"
1946
1947         exhaust_all_precreations 0x215
1948         reset_enospc
1949
1950         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1951
1952         touch $DIR/$tdir/$tfile
1953         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1954         # all except ost1
1955         for (( i=1; i < OSTCOUNT; i++ )); do
1956                 do_facet ost$i lctl set_param fail_loc=0x705
1957         done
1958         local START=`date +%s`
1959         createmany -o $DIR/$tdir/$tfile 32
1960
1961         local FINISH=`date +%s`
1962         local TIMEOUT=`lctl get_param -n timeout`
1963         local PROCESS=$((FINISH - START))
1964         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1965                error "$FINISH - $START >= $TIMEOUT / 2"
1966         sleep $((TIMEOUT / 2 - PROCESS))
1967         reset_enospc
1968 }
1969 run_test 27v "skip object creation on slow OST"
1970
1971 test_27w() { # bug 10997
1972         test_mkdir $DIR/$tdir
1973         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1974         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1975                 error "stripe size $size != 65536" || true
1976         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1977                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1978 }
1979 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1980
1981 test_27wa() {
1982         [[ $OSTCOUNT -lt 2 ]] &&
1983                 skip_env "skipping multiple stripe count/offset test"
1984
1985         test_mkdir $DIR/$tdir
1986         for i in $(seq 1 $OSTCOUNT); do
1987                 offset=$((i - 1))
1988                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1989                         error "setstripe -c $i -i $offset failed"
1990                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1991                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1992                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1993                 [ $index -ne $offset ] &&
1994                         error "stripe offset $index != $offset" || true
1995         done
1996 }
1997 run_test 27wa "check $LFS setstripe -c -i options"
1998
1999 test_27x() {
2000         remote_ost_nodsh && skip "remote OST with nodsh"
2001         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2003
2004         OFFSET=$(($OSTCOUNT - 1))
2005         OSTIDX=0
2006         local OST=$(ostname_from_index $OSTIDX)
2007
2008         test_mkdir $DIR/$tdir
2009         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2010         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2011         sleep_maxage
2012         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2013         for i in $(seq 0 $OFFSET); do
2014                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2015                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2016                 error "OST0 was degraded but new created file still use it"
2017         done
2018         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2019 }
2020 run_test 27x "create files while OST0 is degraded"
2021
2022 test_27y() {
2023         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2024         remote_mds_nodsh && skip "remote MDS with nodsh"
2025         remote_ost_nodsh && skip "remote OST with nodsh"
2026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2027
2028         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2029         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2030                 osp.$mdtosc.prealloc_last_id)
2031         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2032                 osp.$mdtosc.prealloc_next_id)
2033         local fcount=$((last_id - next_id))
2034         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2035         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2036
2037         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2038                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2039         local OST_DEACTIVE_IDX=-1
2040         local OSC
2041         local OSTIDX
2042         local OST
2043
2044         for OSC in $MDS_OSCS; do
2045                 OST=$(osc_to_ost $OSC)
2046                 OSTIDX=$(index_from_ostuuid $OST)
2047                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2048                         OST_DEACTIVE_IDX=$OSTIDX
2049                 fi
2050                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2051                         echo $OSC "is Deactivated:"
2052                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2053                 fi
2054         done
2055
2056         OSTIDX=$(index_from_ostuuid $OST)
2057         test_mkdir $DIR/$tdir
2058         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2059
2060         for OSC in $MDS_OSCS; do
2061                 OST=$(osc_to_ost $OSC)
2062                 OSTIDX=$(index_from_ostuuid $OST)
2063                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2064                         echo $OST "is degraded:"
2065                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2066                                                 obdfilter.$OST.degraded=1
2067                 fi
2068         done
2069
2070         sleep_maxage
2071         createmany -o $DIR/$tdir/$tfile $fcount
2072
2073         for OSC in $MDS_OSCS; do
2074                 OST=$(osc_to_ost $OSC)
2075                 OSTIDX=$(index_from_ostuuid $OST)
2076                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2077                         echo $OST "is recovered from degraded:"
2078                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2079                                                 obdfilter.$OST.degraded=0
2080                 else
2081                         do_facet $SINGLEMDS lctl --device %$OSC activate
2082                 fi
2083         done
2084
2085         # all osp devices get activated, hence -1 stripe count restored
2086         local stripe_count=0
2087
2088         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2089         # devices get activated.
2090         sleep_maxage
2091         $LFS setstripe -c -1 $DIR/$tfile
2092         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2093         rm -f $DIR/$tfile
2094         [ $stripe_count -ne $OSTCOUNT ] &&
2095                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2096         return 0
2097 }
2098 run_test 27y "create files while OST0 is degraded and the rest inactive"
2099
2100 check_seq_oid()
2101 {
2102         log "check file $1"
2103
2104         lmm_count=$($LFS getstripe -c $1)
2105         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2106         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2107
2108         local old_ifs="$IFS"
2109         IFS=$'[:]'
2110         fid=($($LFS path2fid $1))
2111         IFS="$old_ifs"
2112
2113         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2114         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2115
2116         # compare lmm_seq and lu_fid->f_seq
2117         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2118         # compare lmm_object_id and lu_fid->oid
2119         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2120
2121         # check the trusted.fid attribute of the OST objects of the file
2122         local have_obdidx=false
2123         local stripe_nr=0
2124         $LFS getstripe $1 | while read obdidx oid hex seq; do
2125                 # skip lines up to and including "obdidx"
2126                 [ -z "$obdidx" ] && break
2127                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2128                 $have_obdidx || continue
2129
2130                 local ost=$((obdidx + 1))
2131                 local dev=$(ostdevname $ost)
2132                 local oid_hex
2133
2134                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2135
2136                 seq=$(echo $seq | sed -e "s/^0x//g")
2137                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2138                         oid_hex=$(echo $oid)
2139                 else
2140                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2141                 fi
2142                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2143
2144                 local ff=""
2145                 #
2146                 # Don't unmount/remount the OSTs if we don't need to do that.
2147                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2148                 # update too, until that use mount/ll_decode_filter_fid/mount.
2149                 # Re-enable when debugfs will understand new filter_fid.
2150                 #
2151                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2152                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2153                                 $dev 2>/dev/null" | grep "parent=")
2154                 fi
2155                 if [ -z "$ff" ]; then
2156                         stop ost$ost
2157                         mount_fstype ost$ost
2158                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2159                                 $(facet_mntpt ost$ost)/$obj_file)
2160                         unmount_fstype ost$ost
2161                         start ost$ost $dev $OST_MOUNT_OPTS
2162                         clients_up
2163                 fi
2164
2165                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2166
2167                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2168
2169                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2170                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2171                 #
2172                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2173                 #       stripe_size=1048576 component_id=1 component_start=0 \
2174                 #       component_end=33554432
2175                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2176                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2177                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2178                 local ff_pstripe
2179                 if grep -q 'stripe=' <<<$ff; then
2180                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2181                 else
2182                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2183                         # into f_ver in this case.  See comment on ff_parent.
2184                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2185                 fi
2186
2187                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2188                 [ $ff_pseq = $lmm_seq ] ||
2189                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2190                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2191                 [ $ff_poid = $lmm_oid ] ||
2192                         error "FF parent OID $ff_poid != $lmm_oid"
2193                 (($ff_pstripe == $stripe_nr)) ||
2194                         error "FF stripe $ff_pstripe != $stripe_nr"
2195
2196                 stripe_nr=$((stripe_nr + 1))
2197                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2198                         continue
2199                 if grep -q 'stripe_count=' <<<$ff; then
2200                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2201                                             -e 's/ .*//' <<<$ff)
2202                         [ $lmm_count = $ff_scnt ] ||
2203                                 error "FF stripe count $lmm_count != $ff_scnt"
2204                 fi
2205         done
2206 }
2207
2208 test_27z() {
2209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2210         remote_ost_nodsh && skip "remote OST with nodsh"
2211
2212         test_mkdir $DIR/$tdir
2213         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2214                 { error "setstripe -c -1 failed"; return 1; }
2215         # We need to send a write to every object to get parent FID info set.
2216         # This _should_ also work for setattr, but does not currently.
2217         # touch $DIR/$tdir/$tfile-1 ||
2218         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2219                 { error "dd $tfile-1 failed"; return 2; }
2220         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2221                 { error "setstripe -c -1 failed"; return 3; }
2222         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2223                 { error "dd $tfile-2 failed"; return 4; }
2224
2225         # make sure write RPCs have been sent to OSTs
2226         sync; sleep 5; sync
2227
2228         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2229         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2230 }
2231 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2232
2233 test_27A() { # b=19102
2234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2235
2236         save_layout_restore_at_exit $MOUNT
2237         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2238         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2239                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2240         local default_size=$($LFS getstripe -S $MOUNT)
2241         local default_offset=$($LFS getstripe -i $MOUNT)
2242         local dsize=$(do_facet $SINGLEMDS \
2243                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2244         [ $default_size -eq $dsize ] ||
2245                 error "stripe size $default_size != $dsize"
2246         [ $default_offset -eq -1 ] ||
2247                 error "stripe offset $default_offset != -1"
2248 }
2249 run_test 27A "check filesystem-wide default LOV EA values"
2250
2251 test_27B() { # LU-2523
2252         test_mkdir $DIR/$tdir
2253         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2254         touch $DIR/$tdir/f0
2255         # open f1 with O_LOV_DELAY_CREATE
2256         # rename f0 onto f1
2257         # call setstripe ioctl on open file descriptor for f1
2258         # close
2259         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2260                 $DIR/$tdir/f0
2261
2262         rm -f $DIR/$tdir/f1
2263         # open f1 with O_LOV_DELAY_CREATE
2264         # unlink f1
2265         # call setstripe ioctl on open file descriptor for f1
2266         # close
2267         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2268
2269         # Allow multiop to fail in imitation of NFS's busted semantics.
2270         true
2271 }
2272 run_test 27B "call setstripe on open unlinked file/rename victim"
2273
2274 # 27C family tests full striping and overstriping
2275 test_27Ca() { #LU-2871
2276         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2277
2278         declare -a ost_idx
2279         local index
2280         local found
2281         local i
2282         local j
2283
2284         test_mkdir $DIR/$tdir
2285         cd $DIR/$tdir
2286         for i in $(seq 0 $((OSTCOUNT - 1))); do
2287                 # set stripe across all OSTs starting from OST$i
2288                 $LFS setstripe -i $i -c -1 $tfile$i
2289                 # get striping information
2290                 ost_idx=($($LFS getstripe $tfile$i |
2291                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2292                 echo ${ost_idx[@]}
2293
2294                 # check the layout
2295                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2296                         error "${#ost_idx[@]} != $OSTCOUNT"
2297
2298                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2299                         found=0
2300                         for j in $(echo ${ost_idx[@]}); do
2301                                 if [ $index -eq $j ]; then
2302                                         found=1
2303                                         break
2304                                 fi
2305                         done
2306                         [ $found = 1 ] ||
2307                                 error "Can not find $index in ${ost_idx[@]}"
2308                 done
2309         done
2310 }
2311 run_test 27Ca "check full striping across all OSTs"
2312
2313 test_27Cb() {
2314         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2315                 skip "server does not support overstriping"
2316         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2317                 skip_env "too many osts, skipping"
2318
2319         test_mkdir -p $DIR/$tdir
2320         local setcount=$(($OSTCOUNT * 2))
2321         [ $setcount -ge 160 ] || large_xattr_enabled ||
2322                 skip_env "ea_inode feature disabled"
2323
2324         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2325                 error "setstripe failed"
2326
2327         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2328         [ $count -eq $setcount ] ||
2329                 error "stripe count $count, should be $setcount"
2330
2331         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2332                 error "overstriped should be set in pattern"
2333
2334         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2335                 error "dd failed"
2336 }
2337 run_test 27Cb "more stripes than OSTs with -C"
2338
2339 test_27Cc() {
2340         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2341                 skip "server does not support overstriping"
2342         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2343
2344         test_mkdir -p $DIR/$tdir
2345         local setcount=$(($OSTCOUNT - 1))
2346
2347         [ $setcount -ge 160 ] || large_xattr_enabled ||
2348                 skip_env "ea_inode feature disabled"
2349
2350         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2351                 error "setstripe failed"
2352
2353         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2354         [ $count -eq $setcount ] ||
2355                 error "stripe count $count, should be $setcount"
2356
2357         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2358                 error "overstriped should not be set in pattern"
2359
2360         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2361                 error "dd failed"
2362 }
2363 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2364
2365 test_27Cd() {
2366         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2367                 skip "server does not support overstriping"
2368         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2369         large_xattr_enabled || skip_env "ea_inode feature disabled"
2370
2371         test_mkdir -p $DIR/$tdir
2372         local setcount=$LOV_MAX_STRIPE_COUNT
2373
2374         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2375                 error "setstripe failed"
2376
2377         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2378         [ $count -eq $setcount ] ||
2379                 error "stripe count $count, should be $setcount"
2380
2381         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2382                 error "overstriped should be set in pattern"
2383
2384         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2385                 error "dd failed"
2386
2387         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2388 }
2389 run_test 27Cd "test maximum stripe count"
2390
2391 test_27Ce() {
2392         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2393                 skip "server does not support overstriping"
2394         test_mkdir -p $DIR/$tdir
2395
2396         pool_add $TESTNAME || error "Pool creation failed"
2397         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2398
2399         local setcount=8
2400
2401         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2402                 error "setstripe failed"
2403
2404         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2405         [ $count -eq $setcount ] ||
2406                 error "stripe count $count, should be $setcount"
2407
2408         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2409                 error "overstriped should be set in pattern"
2410
2411         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2412                 error "dd failed"
2413
2414         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2415 }
2416 run_test 27Ce "test pool with overstriping"
2417
2418 test_27Cf() {
2419         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2420                 skip "server does not support overstriping"
2421         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2422                 skip_env "too many osts, skipping"
2423
2424         test_mkdir -p $DIR/$tdir
2425
2426         local setcount=$(($OSTCOUNT * 2))
2427         [ $setcount -ge 160 ] || large_xattr_enabled ||
2428                 skip_env "ea_inode feature disabled"
2429
2430         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2431                 error "setstripe failed"
2432
2433         echo 1 > $DIR/$tdir/$tfile
2434
2435         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2436         [ $count -eq $setcount ] ||
2437                 error "stripe count $count, should be $setcount"
2438
2439         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2440                 error "overstriped should be set in pattern"
2441
2442         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2443                 error "dd failed"
2444
2445         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2446 }
2447 run_test 27Cf "test default inheritance with overstriping"
2448
2449 test_27D() {
2450         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2451         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2452         remote_mds_nodsh && skip "remote MDS with nodsh"
2453
2454         local POOL=${POOL:-testpool}
2455         local first_ost=0
2456         local last_ost=$(($OSTCOUNT - 1))
2457         local ost_step=1
2458         local ost_list=$(seq $first_ost $ost_step $last_ost)
2459         local ost_range="$first_ost $last_ost $ost_step"
2460
2461         if ! combined_mgs_mds ; then
2462                 mount_mgs_client
2463         fi
2464
2465         test_mkdir $DIR/$tdir
2466         pool_add $POOL || error "pool_add failed"
2467         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2468
2469         local skip27D
2470         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2471                 skip27D+="-s 29"
2472         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2473                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2474                         skip27D+=" -s 30,31"
2475         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code $SEL_VER) ] &&
2476                 skip27D+="-s 32"
2477         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2478           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2479                 skip27D+=" -s 32,33"
2480         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2481                 error "llapi_layout_test failed"
2482
2483         destroy_test_pools || error "destroy test pools failed"
2484
2485         if ! combined_mgs_mds ; then
2486                 umount_mgs_client
2487         fi
2488 }
2489 run_test 27D "validate llapi_layout API"
2490
2491 # Verify that default_easize is increased from its initial value after
2492 # accessing a widely striped file.
2493 test_27E() {
2494         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2495         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2496                 skip "client does not have LU-3338 fix"
2497
2498         # 72 bytes is the minimum space required to store striping
2499         # information for a file striped across one OST:
2500         # (sizeof(struct lov_user_md_v3) +
2501         #  sizeof(struct lov_user_ost_data_v1))
2502         local min_easize=72
2503         $LCTL set_param -n llite.*.default_easize $min_easize ||
2504                 error "lctl set_param failed"
2505         local easize=$($LCTL get_param -n llite.*.default_easize)
2506
2507         [ $easize -eq $min_easize ] ||
2508                 error "failed to set default_easize"
2509
2510         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2511                 error "setstripe failed"
2512         # In order to ensure stat() call actually talks to MDS we need to
2513         # do something drastic to this file to shake off all lock, e.g.
2514         # rename it (kills lookup lock forcing cache cleaning)
2515         mv $DIR/$tfile $DIR/${tfile}-1
2516         ls -l $DIR/${tfile}-1
2517         rm $DIR/${tfile}-1
2518
2519         easize=$($LCTL get_param -n llite.*.default_easize)
2520
2521         [ $easize -gt $min_easize ] ||
2522                 error "default_easize not updated"
2523 }
2524 run_test 27E "check that default extended attribute size properly increases"
2525
2526 test_27F() { # LU-5346/LU-7975
2527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2528         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2529         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2530                 skip "Need MDS version at least 2.8.51"
2531         remote_ost_nodsh && skip "remote OST with nodsh"
2532
2533         test_mkdir $DIR/$tdir
2534         rm -f $DIR/$tdir/f0
2535         $LFS setstripe -c 2 $DIR/$tdir
2536
2537         # stop all OSTs to reproduce situation for LU-7975 ticket
2538         for num in $(seq $OSTCOUNT); do
2539                 stop ost$num
2540         done
2541
2542         # open/create f0 with O_LOV_DELAY_CREATE
2543         # truncate f0 to a non-0 size
2544         # close
2545         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2546
2547         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2548         # open/write it again to force delayed layout creation
2549         cat /etc/hosts > $DIR/$tdir/f0 &
2550         catpid=$!
2551
2552         # restart OSTs
2553         for num in $(seq $OSTCOUNT); do
2554                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2555                         error "ost$num failed to start"
2556         done
2557
2558         wait $catpid || error "cat failed"
2559
2560         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2561         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2562                 error "wrong stripecount"
2563
2564 }
2565 run_test 27F "Client resend delayed layout creation with non-zero size"
2566
2567 test_27G() { #LU-10629
2568         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2569                 skip "Need MDS version at least 2.11.51"
2570         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2571         remote_mds_nodsh && skip "remote MDS with nodsh"
2572         local POOL=${POOL:-testpool}
2573         local ostrange="0 0 1"
2574
2575         test_mkdir $DIR/$tdir
2576         pool_add $POOL || error "pool_add failed"
2577         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2578         $LFS setstripe -p $POOL $DIR/$tdir
2579
2580         local pool=$($LFS getstripe -p $DIR/$tdir)
2581
2582         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2583
2584         $LFS setstripe -d $DIR/$tdir
2585
2586         pool=$($LFS getstripe -p $DIR/$tdir)
2587
2588         rmdir $DIR/$tdir
2589
2590         [ -z "$pool" ] || error "'$pool' is not empty"
2591 }
2592 run_test 27G "Clear OST pool from stripe"
2593
2594 test_27H() {
2595         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2596                 skip "Need MDS version newer than 2.11.54"
2597         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2598         test_mkdir $DIR/$tdir
2599         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2600         touch $DIR/$tdir/$tfile
2601         $LFS getstripe -c $DIR/$tdir/$tfile
2602         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2603                 error "two-stripe file doesn't have two stripes"
2604
2605         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2606         $LFS getstripe -y $DIR/$tdir/$tfile
2607         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2608              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2609                 error "expected l_ost_idx: [02]$ not matched"
2610
2611         # make sure ost list has been cleared
2612         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2613         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2614                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2615         touch $DIR/$tdir/f3
2616         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2617 }
2618 run_test 27H "Set specific OSTs stripe"
2619
2620 test_27I() {
2621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2622         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2623         local pool=$TESTNAME
2624         local ostrange="1 1 1"
2625
2626         save_layout_restore_at_exit $MOUNT
2627         $LFS setstripe -c 2 -i 0 $MOUNT
2628         pool_add $pool || error "pool_add failed"
2629         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2630         test_mkdir $DIR/$tdir
2631         $LFS setstripe -p $pool $DIR/$tdir
2632         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2633         $LFS getstripe $DIR/$tdir/$tfile
2634 }
2635 run_test 27I "check that root dir striping does not break parent dir one"
2636
2637 test_27J() {
2638         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
2639                 skip "Need MDS version newer than 2.12.51"
2640
2641         test_mkdir $DIR/$tdir
2642         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2643         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2644
2645         # create foreign file (raw way)
2646         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2647                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2648
2649         # verify foreign file (raw way)
2650         parse_foreign_file -f $DIR/$tdir/$tfile |
2651                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2652                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2653         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2654                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2655         parse_foreign_file -f $DIR/$tdir/$tfile |
2656                 grep "lov_foreign_size: 73" ||
2657                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2658         parse_foreign_file -f $DIR/$tdir/$tfile |
2659                 grep "lov_foreign_type: 1" ||
2660                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2661         parse_foreign_file -f $DIR/$tdir/$tfile |
2662                 grep "lov_foreign_flags: 0x0000DA08" ||
2663                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2664         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2665                 grep "lov_foreign_value: 0x" |
2666                 sed -e 's/lov_foreign_value: 0x//')
2667         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2668         [[ $lov = ${lov2// /} ]] ||
2669                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2670
2671         # create foreign file (lfs + API)
2672         $LFS setstripe --foreign=daos --flags 0xda08 \
2673                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2674                 error "$DIR/$tdir/${tfile}2: create failed"
2675
2676         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2677                 grep "lfm_magic:.*0x0BD70BD0" ||
2678                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2679         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2680         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2681                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2682         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2683                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2684         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2685                 grep "lfm_flags:.*0x0000DA08" ||
2686                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2687         $LFS getstripe $DIR/$tdir/${tfile}2 |
2688                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2689                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2690
2691         # modify striping should fail
2692         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2693                 error "$DIR/$tdir/$tfile: setstripe should fail"
2694         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2695                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2696
2697         # R/W should fail
2698         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2699         cat $DIR/$tdir/${tfile}2 &&
2700                 error "$DIR/$tdir/${tfile}2: read should fail"
2701         cat /etc/passwd > $DIR/$tdir/$tfile &&
2702                 error "$DIR/$tdir/$tfile: write should fail"
2703         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2704                 error "$DIR/$tdir/${tfile}2: write should fail"
2705
2706         # chmod should work
2707         chmod 222 $DIR/$tdir/$tfile ||
2708                 error "$DIR/$tdir/$tfile: chmod failed"
2709         chmod 222 $DIR/$tdir/${tfile}2 ||
2710                 error "$DIR/$tdir/${tfile}2: chmod failed"
2711
2712         # chown should work
2713         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2714                 error "$DIR/$tdir/$tfile: chown failed"
2715         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2716                 error "$DIR/$tdir/${tfile}2: chown failed"
2717
2718         # rename should work
2719         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2720                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2721         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2722                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2723
2724         #remove foreign file
2725         rm $DIR/$tdir/${tfile}.new ||
2726                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2727         rm $DIR/$tdir/${tfile}2.new ||
2728                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2729 }
2730 run_test 27J "basic ops on file with foreign LOV"
2731
2732 test_27K() {
2733         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
2734                 skip "Need MDS version newer than 2.12.49"
2735
2736         test_mkdir $DIR/$tdir
2737         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2738         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2739
2740         # create foreign dir (raw way)
2741         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2742                 error "create_foreign_dir FAILED"
2743
2744         # verify foreign dir (raw way)
2745         parse_foreign_dir -d $DIR/$tdir/$tdir |
2746                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2747                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2748         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2749                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2750         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2751                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2752         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2753                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2754         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2755                 grep "lmv_foreign_value: 0x" |
2756                 sed 's/lmv_foreign_value: 0x//')
2757         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2758                 sed 's/ //g')
2759         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2760
2761         # create foreign dir (lfs + API)
2762         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2763                 $DIR/$tdir/${tdir}2 ||
2764                 error "$DIR/$tdir/${tdir}2: create failed"
2765
2766         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2767                 grep "lfm_magic:.*0x0CD50CD0" ||
2768                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2769         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2770         # - sizeof(lfm_type) - sizeof(lfm_flags)
2771         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2772                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2773         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2774                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2775         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2776                 grep "lfm_flags:.*0x0000DA05" ||
2777                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2778         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2779                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2780                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2781
2782         # file create in dir should fail
2783         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2784         touch $DIR/$tdir/${tdir}2/$tfile &&
2785                 "$DIR/${tdir}2: file create should fail"
2786
2787         # chmod should work
2788         chmod 777 $DIR/$tdir/$tdir ||
2789                 error "$DIR/$tdir: chmod failed"
2790         chmod 777 $DIR/$tdir/${tdir}2 ||
2791                 error "$DIR/${tdir}2: chmod failed"
2792
2793         # chown should work
2794         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2795                 error "$DIR/$tdir: chown failed"
2796         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2797                 error "$DIR/${tdir}2: chown failed"
2798
2799         # rename should work
2800         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2801                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2802         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2803                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2804
2805         #remove foreign dir
2806         rmdir $DIR/$tdir/${tdir}.new ||
2807                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2808         rmdir $DIR/$tdir/${tdir}2.new ||
2809                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2810 }
2811 run_test 27K "basic ops on dir with foreign LMV"
2812
2813 # createtest also checks that device nodes are created and
2814 # then visible correctly (#2091)
2815 test_28() { # bug 2091
2816         test_mkdir $DIR/d28
2817         $CREATETEST $DIR/d28/ct || error "createtest failed"
2818 }
2819 run_test 28 "create/mknod/mkdir with bad file types ============"
2820
2821 test_29() {
2822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2823
2824         sync; sleep 1; sync # flush out any dirty pages from previous tests
2825         cancel_lru_locks
2826         test_mkdir $DIR/d29
2827         touch $DIR/d29/foo
2828         log 'first d29'
2829         ls -l $DIR/d29
2830
2831         declare -i LOCKCOUNTORIG=0
2832         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2833                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2834         done
2835         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2836
2837         declare -i LOCKUNUSEDCOUNTORIG=0
2838         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2839                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2840         done
2841
2842         log 'second d29'
2843         ls -l $DIR/d29
2844         log 'done'
2845
2846         declare -i LOCKCOUNTCURRENT=0
2847         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2848                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2849         done
2850
2851         declare -i LOCKUNUSEDCOUNTCURRENT=0
2852         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2853                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2854         done
2855
2856         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2857                 $LCTL set_param -n ldlm.dump_namespaces ""
2858                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2859                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2860                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2861                 return 2
2862         fi
2863         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2864                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2865                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2866                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2867                 return 3
2868         fi
2869 }
2870 run_test 29 "IT_GETATTR regression  ============================"
2871
2872 test_30a() { # was test_30
2873         cp $(which ls) $DIR || cp /bin/ls $DIR
2874         $DIR/ls / || error "Can't execute binary from lustre"
2875         rm $DIR/ls
2876 }
2877 run_test 30a "execute binary from Lustre (execve) =============="
2878
2879 test_30b() {
2880         cp `which ls` $DIR || cp /bin/ls $DIR
2881         chmod go+rx $DIR/ls
2882         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2883         rm $DIR/ls
2884 }
2885 run_test 30b "execute binary from Lustre as non-root ==========="
2886
2887 test_30c() { # b=22376
2888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2889
2890         cp `which ls` $DIR || cp /bin/ls $DIR
2891         chmod a-rw $DIR/ls
2892         cancel_lru_locks mdc
2893         cancel_lru_locks osc
2894         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2895         rm -f $DIR/ls
2896 }
2897 run_test 30c "execute binary from Lustre without read perms ===="
2898
2899 test_31a() {
2900         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2901         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2902 }
2903 run_test 31a "open-unlink file =================================="
2904
2905 test_31b() {
2906         touch $DIR/f31 || error "touch $DIR/f31 failed"
2907         ln $DIR/f31 $DIR/f31b || error "ln failed"
2908         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2909         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2910 }
2911 run_test 31b "unlink file with multiple links while open ======="
2912
2913 test_31c() {
2914         touch $DIR/f31 || error "touch $DIR/f31 failed"
2915         ln $DIR/f31 $DIR/f31c || error "ln failed"
2916         multiop_bg_pause $DIR/f31 O_uc ||
2917                 error "multiop_bg_pause for $DIR/f31 failed"
2918         MULTIPID=$!
2919         $MULTIOP $DIR/f31c Ouc
2920         kill -USR1 $MULTIPID
2921         wait $MULTIPID
2922 }
2923 run_test 31c "open-unlink file with multiple links ============="
2924
2925 test_31d() {
2926         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2927         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2928 }
2929 run_test 31d "remove of open directory ========================="
2930
2931 test_31e() { # bug 2904
2932         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2933 }
2934 run_test 31e "remove of open non-empty directory ==============="
2935
2936 test_31f() { # bug 4554
2937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2938
2939         set -vx
2940         test_mkdir $DIR/d31f
2941         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2942         cp /etc/hosts $DIR/d31f
2943         ls -l $DIR/d31f
2944         $LFS getstripe $DIR/d31f/hosts
2945         multiop_bg_pause $DIR/d31f D_c || return 1
2946         MULTIPID=$!
2947
2948         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2949         test_mkdir $DIR/d31f
2950         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2951         cp /etc/hosts $DIR/d31f
2952         ls -l $DIR/d31f
2953         $LFS getstripe $DIR/d31f/hosts
2954         multiop_bg_pause $DIR/d31f D_c || return 1
2955         MULTIPID2=$!
2956
2957         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2958         wait $MULTIPID || error "first opendir $MULTIPID failed"
2959
2960         sleep 6
2961
2962         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2963         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2964         set +vx
2965 }
2966 run_test 31f "remove of open directory with open-unlink file ==="
2967
2968 test_31g() {
2969         echo "-- cross directory link --"
2970         test_mkdir -c1 $DIR/${tdir}ga
2971         test_mkdir -c1 $DIR/${tdir}gb
2972         touch $DIR/${tdir}ga/f
2973         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2974         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2975         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2976         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2977         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2978 }
2979 run_test 31g "cross directory link==============="
2980
2981 test_31h() {
2982         echo "-- cross directory link --"
2983         test_mkdir -c1 $DIR/${tdir}
2984         test_mkdir -c1 $DIR/${tdir}/dir
2985         touch $DIR/${tdir}/f
2986         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
2987         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
2988         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
2989         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
2990         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
2991 }
2992 run_test 31h "cross directory link under child==============="
2993
2994 test_31i() {
2995         echo "-- cross directory link --"
2996         test_mkdir -c1 $DIR/$tdir
2997         test_mkdir -c1 $DIR/$tdir/dir
2998         touch $DIR/$tdir/dir/f
2999         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3000         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3001         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3002         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3003         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3004 }
3005 run_test 31i "cross directory link under parent==============="
3006
3007 test_31j() {
3008         test_mkdir -c1 -p $DIR/$tdir
3009         test_mkdir -c1 -p $DIR/$tdir/dir1
3010         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3011         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3012         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3013         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3014         return 0
3015 }
3016 run_test 31j "link for directory==============="
3017
3018 test_31k() {
3019         test_mkdir -c1 -p $DIR/$tdir
3020         touch $DIR/$tdir/s
3021         touch $DIR/$tdir/exist
3022         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3023         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3024         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3025         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3026         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3027         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3028         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3029         return 0
3030 }
3031 run_test 31k "link to file: the same, non-existing, dir==============="
3032
3033 test_31m() {
3034         mkdir $DIR/d31m
3035         touch $DIR/d31m/s
3036         mkdir $DIR/d31m2
3037         touch $DIR/d31m2/exist
3038         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3039         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3040         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3041         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3042         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3043         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3044         return 0
3045 }
3046 run_test 31m "link to file: the same, non-existing, dir==============="
3047
3048 test_31n() {
3049         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3050         nlink=$(stat --format=%h $DIR/$tfile)
3051         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3052         local fd=$(free_fd)
3053         local cmd="exec $fd<$DIR/$tfile"
3054         eval $cmd
3055         cmd="exec $fd<&-"
3056         trap "eval $cmd" EXIT
3057         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3058         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3059         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3060         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3061         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3062         eval $cmd
3063 }
3064 run_test 31n "check link count of unlinked file"
3065
3066 link_one() {
3067         local TEMPNAME=$(mktemp $1_XXXXXX)
3068         mlink $TEMPNAME $1 2> /dev/null &&
3069                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
3070         munlink $TEMPNAME
3071 }
3072
3073 test_31o() { # LU-2901
3074         test_mkdir $DIR/$tdir
3075         for LOOP in $(seq 100); do
3076                 rm -f $DIR/$tdir/$tfile*
3077                 for THREAD in $(seq 8); do
3078                         link_one $DIR/$tdir/$tfile.$LOOP &
3079                 done
3080                 wait
3081                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3082                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3083                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3084                         break || true
3085         done
3086 }
3087 run_test 31o "duplicate hard links with same filename"
3088
3089 test_31p() {
3090         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3091
3092         test_mkdir $DIR/$tdir
3093         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3094         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3095
3096         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3097                 error "open unlink test1 failed"
3098         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3099                 error "open unlink test2 failed"
3100
3101         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3102                 error "test1 still exists"
3103         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3104                 error "test2 still exists"
3105 }
3106 run_test 31p "remove of open striped directory"
3107
3108 cleanup_test32_mount() {
3109         local rc=0
3110         trap 0
3111         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3112         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3113         losetup -d $loopdev || true
3114         rm -rf $DIR/$tdir
3115         return $rc
3116 }
3117
3118 test_32a() {
3119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3120
3121         echo "== more mountpoints and symlinks ================="
3122         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3123         trap cleanup_test32_mount EXIT
3124         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3125         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3126                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3127         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3128                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3129         cleanup_test32_mount
3130 }
3131 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3132
3133 test_32b() {
3134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3135
3136         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3137         trap cleanup_test32_mount EXIT
3138         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3139         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3140                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3141         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3142                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3143         cleanup_test32_mount
3144 }
3145 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3146
3147 test_32c() {
3148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3149
3150         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3151         trap cleanup_test32_mount EXIT
3152         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3153         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3154                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3155         test_mkdir -p $DIR/$tdir/d2/test_dir
3156         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3157                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3158         cleanup_test32_mount
3159 }
3160 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3161
3162 test_32d() {
3163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3164
3165         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3166         trap cleanup_test32_mount EXIT
3167         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3168         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3169                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3170         test_mkdir -p $DIR/$tdir/d2/test_dir
3171         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3172                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3173         cleanup_test32_mount
3174 }
3175 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3176
3177 test_32e() {
3178         rm -fr $DIR/$tdir
3179         test_mkdir -p $DIR/$tdir/tmp
3180         local tmp_dir=$DIR/$tdir/tmp
3181         ln -s $DIR/$tdir $tmp_dir/symlink11
3182         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3183         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3184         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3185 }
3186 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3187
3188 test_32f() {
3189         rm -fr $DIR/$tdir
3190         test_mkdir -p $DIR/$tdir/tmp
3191         local tmp_dir=$DIR/$tdir/tmp
3192         ln -s $DIR/$tdir $tmp_dir/symlink11
3193         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3194         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3195         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3196 }
3197 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3198
3199 test_32g() {
3200         local tmp_dir=$DIR/$tdir/tmp
3201         test_mkdir -p $tmp_dir
3202         test_mkdir $DIR/${tdir}2
3203         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3204         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3205         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3206         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3207         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3208         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3209 }
3210 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3211
3212 test_32h() {
3213         rm -fr $DIR/$tdir $DIR/${tdir}2
3214         tmp_dir=$DIR/$tdir/tmp
3215         test_mkdir -p $tmp_dir
3216         test_mkdir $DIR/${tdir}2
3217         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3218         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3219         ls $tmp_dir/symlink12 || error "listing symlink12"
3220         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3221 }
3222 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3223
3224 test_32i() {
3225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3226
3227         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3228         trap cleanup_test32_mount EXIT
3229         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3230         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3231                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3232         touch $DIR/$tdir/test_file
3233         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3234                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3235         cleanup_test32_mount
3236 }
3237 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3238
3239 test_32j() {
3240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3241
3242         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3243         trap cleanup_test32_mount EXIT
3244         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3245         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3246                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3247         touch $DIR/$tdir/test_file
3248         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3249                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3250         cleanup_test32_mount
3251 }
3252 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3253
3254 test_32k() {
3255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3256
3257         rm -fr $DIR/$tdir
3258         trap cleanup_test32_mount EXIT
3259         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3260         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3261                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3262         test_mkdir -p $DIR/$tdir/d2
3263         touch $DIR/$tdir/d2/test_file || error "touch failed"
3264         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3265                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3266         cleanup_test32_mount
3267 }
3268 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3269
3270 test_32l() {
3271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3272
3273         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         test_mkdir -p $DIR/$tdir/d2
3279         touch $DIR/$tdir/d2/test_file || error "touch failed"
3280         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3281                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3282         cleanup_test32_mount
3283 }
3284 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3285
3286 test_32m() {
3287         rm -fr $DIR/d32m
3288         test_mkdir -p $DIR/d32m/tmp
3289         TMP_DIR=$DIR/d32m/tmp
3290         ln -s $DIR $TMP_DIR/symlink11
3291         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3292         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3293                 error "symlink11 not a link"
3294         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3295                 error "symlink01 not a link"
3296 }
3297 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3298
3299 test_32n() {
3300         rm -fr $DIR/d32n
3301         test_mkdir -p $DIR/d32n/tmp
3302         TMP_DIR=$DIR/d32n/tmp
3303         ln -s $DIR $TMP_DIR/symlink11
3304         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3305         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3306         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3307 }
3308 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3309
3310 test_32o() {
3311         touch $DIR/$tfile
3312         test_mkdir -p $DIR/d32o/tmp
3313         TMP_DIR=$DIR/d32o/tmp
3314         ln -s $DIR/$tfile $TMP_DIR/symlink12
3315         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3316         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3317                 error "symlink12 not a link"
3318         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3319         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3320                 error "$DIR/d32o/tmp/symlink12 not file type"
3321         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3322                 error "$DIR/d32o/symlink02 not file type"
3323 }
3324 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3325
3326 test_32p() {
3327         log 32p_1
3328         rm -fr $DIR/d32p
3329         log 32p_2
3330         rm -f $DIR/$tfile
3331         log 32p_3
3332         touch $DIR/$tfile
3333         log 32p_4
3334         test_mkdir -p $DIR/d32p/tmp
3335         log 32p_5
3336         TMP_DIR=$DIR/d32p/tmp
3337         log 32p_6
3338         ln -s $DIR/$tfile $TMP_DIR/symlink12
3339         log 32p_7
3340         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3341         log 32p_8
3342         cat $DIR/d32p/tmp/symlink12 ||
3343                 error "Can't open $DIR/d32p/tmp/symlink12"
3344         log 32p_9
3345         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3346         log 32p_10
3347 }
3348 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3349
3350 test_32q() {
3351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3352
3353         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3354         trap cleanup_test32_mount EXIT
3355         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3356         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3357         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3358                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3359         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3360         cleanup_test32_mount
3361 }
3362 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3363
3364 test_32r() {
3365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3366
3367         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3368         trap cleanup_test32_mount EXIT
3369         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3370         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3371         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3372                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3373         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3374         cleanup_test32_mount
3375 }
3376 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3377
3378 test_33aa() {
3379         rm -f $DIR/$tfile
3380         touch $DIR/$tfile
3381         chmod 444 $DIR/$tfile
3382         chown $RUNAS_ID $DIR/$tfile
3383         log 33_1
3384         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3385         log 33_2
3386 }
3387 run_test 33aa "write file with mode 444 (should return error)"
3388
3389 test_33a() {
3390         rm -fr $DIR/$tdir
3391         test_mkdir $DIR/$tdir
3392         chown $RUNAS_ID $DIR/$tdir
3393         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3394                 error "$RUNAS create $tdir/$tfile failed"
3395         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3396                 error "open RDWR" || true
3397 }
3398 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3399
3400 test_33b() {
3401         rm -fr $DIR/$tdir
3402         test_mkdir $DIR/$tdir
3403         chown $RUNAS_ID $DIR/$tdir
3404         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3405 }
3406 run_test 33b "test open file with malformed flags (No panic)"
3407
3408 test_33c() {
3409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3410         remote_ost_nodsh && skip "remote OST with nodsh"
3411
3412         local ostnum
3413         local ostname
3414         local write_bytes
3415         local all_zeros
3416
3417         all_zeros=:
3418         rm -fr $DIR/$tdir
3419         test_mkdir $DIR/$tdir
3420         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3421
3422         sync
3423         for ostnum in $(seq $OSTCOUNT); do
3424                 # test-framework's OST numbering is one-based, while Lustre's
3425                 # is zero-based
3426                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3427                 # Parsing llobdstat's output sucks; we could grep the /proc
3428                 # path, but that's likely to not be as portable as using the
3429                 # llobdstat utility.  So we parse lctl output instead.
3430                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3431                         obdfilter/$ostname/stats |
3432                         awk '/^write_bytes/ {print $7}' )
3433                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3434                 if (( ${write_bytes:-0} > 0 ))
3435                 then
3436                         all_zeros=false
3437                         break;
3438                 fi
3439         done
3440
3441         $all_zeros || return 0
3442
3443         # Write four bytes
3444         echo foo > $DIR/$tdir/bar
3445         # Really write them
3446         sync
3447
3448         # Total up write_bytes after writing.  We'd better find non-zeros.
3449         for ostnum in $(seq $OSTCOUNT); do
3450                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3451                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3452                         obdfilter/$ostname/stats |
3453                         awk '/^write_bytes/ {print $7}' )
3454                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3455                 if (( ${write_bytes:-0} > 0 ))
3456                 then
3457                         all_zeros=false
3458                         break;
3459                 fi
3460         done
3461
3462         if $all_zeros
3463         then
3464                 for ostnum in $(seq $OSTCOUNT); do
3465                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3466                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3467                         do_facet ost$ostnum lctl get_param -n \
3468                                 obdfilter/$ostname/stats
3469                 done
3470                 error "OST not keeping write_bytes stats (b22312)"
3471         fi
3472 }
3473 run_test 33c "test llobdstat and write_bytes"
3474
3475 test_33d() {
3476         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3478
3479         local MDTIDX=1
3480         local remote_dir=$DIR/$tdir/remote_dir
3481
3482         test_mkdir $DIR/$tdir
3483         $LFS mkdir -i $MDTIDX $remote_dir ||
3484                 error "create remote directory failed"
3485
3486         touch $remote_dir/$tfile
3487         chmod 444 $remote_dir/$tfile
3488         chown $RUNAS_ID $remote_dir/$tfile
3489
3490         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3491
3492         chown $RUNAS_ID $remote_dir
3493         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3494                                         error "create" || true
3495         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3496                                     error "open RDWR" || true
3497         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3498 }
3499 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3500
3501 test_33e() {
3502         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3503
3504         mkdir $DIR/$tdir
3505
3506         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3507         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3508         mkdir $DIR/$tdir/local_dir
3509
3510         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3511         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3512         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3513
3514         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3515                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3516
3517         rmdir $DIR/$tdir/* || error "rmdir failed"
3518
3519         umask 777
3520         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3521         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3522         mkdir $DIR/$tdir/local_dir
3523
3524         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3525         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3526         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3527
3528         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3529                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3530
3531         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3532
3533         umask 000
3534         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3535         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3536         mkdir $DIR/$tdir/local_dir
3537
3538         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3539         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3540         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3541
3542         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3543                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3544 }
3545 run_test 33e "mkdir and striped directory should have same mode"
3546
3547 cleanup_33f() {
3548         trap 0
3549         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3550 }
3551
3552 test_33f() {
3553         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3554         remote_mds_nodsh && skip "remote MDS with nodsh"
3555
3556         mkdir $DIR/$tdir
3557         chmod go+rwx $DIR/$tdir
3558         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3559         trap cleanup_33f EXIT
3560
3561         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3562                 error "cannot create striped directory"
3563
3564         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3565                 error "cannot create files in striped directory"
3566
3567         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3568                 error "cannot remove files in striped directory"
3569
3570         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3571                 error "cannot remove striped directory"
3572
3573         cleanup_33f
3574 }
3575 run_test 33f "nonroot user can create, access, and remove a striped directory"
3576
3577 test_33g() {
3578         mkdir -p $DIR/$tdir/dir2
3579
3580         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3581         echo $err
3582         [[ $err =~ "exists" ]] || error "Not exists error"
3583 }
3584 run_test 33g "nonroot user create already existing root created file"
3585
3586 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3587 test_34a() {
3588         rm -f $DIR/f34
3589         $MCREATE $DIR/f34 || error "mcreate failed"
3590         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3591                 error "getstripe failed"
3592         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3593         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3594                 error "getstripe failed"
3595         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3596                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3597 }
3598 run_test 34a "truncate file that has not been opened ==========="
3599
3600 test_34b() {
3601         [ ! -f $DIR/f34 ] && test_34a
3602         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3603                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3604         $OPENFILE -f O_RDONLY $DIR/f34
3605         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3606                 error "getstripe failed"
3607         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3608                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3609 }
3610 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3611
3612 test_34c() {
3613         [ ! -f $DIR/f34 ] && test_34a
3614         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3615                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3616         $OPENFILE -f O_RDWR $DIR/f34
3617         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3618                 error "$LFS getstripe failed"
3619         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3620                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3621 }
3622 run_test 34c "O_RDWR opening file-with-size works =============="
3623
3624 test_34d() {
3625         [ ! -f $DIR/f34 ] && test_34a
3626         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3627                 error "dd failed"
3628         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3629                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3630         rm $DIR/f34
3631 }
3632 run_test 34d "write to sparse file ============================="
3633
3634 test_34e() {
3635         rm -f $DIR/f34e
3636         $MCREATE $DIR/f34e || error "mcreate failed"
3637         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3638         $CHECKSTAT -s 1000 $DIR/f34e ||
3639                 error "Size of $DIR/f34e not equal to 1000 bytes"
3640         $OPENFILE -f O_RDWR $DIR/f34e
3641         $CHECKSTAT -s 1000 $DIR/f34e ||
3642                 error "Size of $DIR/f34e not equal to 1000 bytes"
3643 }
3644 run_test 34e "create objects, some with size and some without =="
3645
3646 test_34f() { # bug 6242, 6243
3647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3648
3649         SIZE34F=48000
3650         rm -f $DIR/f34f
3651         $MCREATE $DIR/f34f || error "mcreate failed"
3652         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3653         dd if=$DIR/f34f of=$TMP/f34f
3654         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3655         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3656         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3657         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3658         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3659 }
3660 run_test 34f "read from a file with no objects until EOF ======="
3661
3662 test_34g() {
3663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3664
3665         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3666                 error "dd failed"
3667         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3668         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3669                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3670         cancel_lru_locks osc
3671         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3672                 error "wrong size after lock cancel"
3673
3674         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3675         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3676                 error "expanding truncate failed"
3677         cancel_lru_locks osc
3678         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3679                 error "wrong expanded size after lock cancel"
3680 }
3681 run_test 34g "truncate long file ==============================="
3682
3683 test_34h() {
3684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3685
3686         local gid=10
3687         local sz=1000
3688
3689         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3690         sync # Flush the cache so that multiop below does not block on cache
3691              # flush when getting the group lock
3692         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3693         MULTIPID=$!
3694
3695         # Since just timed wait is not good enough, let's do a sync write
3696         # that way we are sure enough time for a roundtrip + processing
3697         # passed + 2 seconds of extra margin.
3698         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3699         rm $DIR/${tfile}-1
3700         sleep 2
3701
3702         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3703                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3704                 kill -9 $MULTIPID
3705         fi
3706         wait $MULTIPID
3707         local nsz=`stat -c %s $DIR/$tfile`
3708         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3709 }
3710 run_test 34h "ftruncate file under grouplock should not block"
3711
3712 test_35a() {
3713         cp /bin/sh $DIR/f35a
3714         chmod 444 $DIR/f35a
3715         chown $RUNAS_ID $DIR/f35a
3716         $RUNAS $DIR/f35a && error || true
3717         rm $DIR/f35a
3718 }
3719 run_test 35a "exec file with mode 444 (should return and not leak)"
3720
3721 test_36a() {
3722         rm -f $DIR/f36
3723         utime $DIR/f36 || error "utime failed for MDS"
3724 }
3725 run_test 36a "MDS utime check (mknod, utime)"
3726
3727 test_36b() {
3728         echo "" > $DIR/f36
3729         utime $DIR/f36 || error "utime failed for OST"
3730 }
3731 run_test 36b "OST utime check (open, utime)"
3732
3733 test_36c() {
3734         rm -f $DIR/d36/f36
3735         test_mkdir $DIR/d36
3736         chown $RUNAS_ID $DIR/d36
3737         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3738 }
3739 run_test 36c "non-root MDS utime check (mknod, utime)"
3740
3741 test_36d() {
3742         [ ! -d $DIR/d36 ] && test_36c
3743         echo "" > $DIR/d36/f36
3744         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3745 }
3746 run_test 36d "non-root OST utime check (open, utime)"
3747
3748 test_36e() {
3749         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3750
3751         test_mkdir $DIR/$tdir
3752         touch $DIR/$tdir/$tfile
3753         $RUNAS utime $DIR/$tdir/$tfile &&
3754                 error "utime worked, expected failure" || true
3755 }
3756 run_test 36e "utime on non-owned file (should return error)"
3757
3758 subr_36fh() {
3759         local fl="$1"
3760         local LANG_SAVE=$LANG
3761         local LC_LANG_SAVE=$LC_LANG
3762         export LANG=C LC_LANG=C # for date language
3763
3764         DATESTR="Dec 20  2000"
3765         test_mkdir $DIR/$tdir
3766         lctl set_param fail_loc=$fl
3767         date; date +%s
3768         cp /etc/hosts $DIR/$tdir/$tfile
3769         sync & # write RPC generated with "current" inode timestamp, but delayed
3770         sleep 1
3771         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3772         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3773         cancel_lru_locks $OSC
3774         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3775         date; date +%s
3776         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3777                 echo "BEFORE: $LS_BEFORE" && \
3778                 echo "AFTER : $LS_AFTER" && \
3779                 echo "WANT  : $DATESTR" && \
3780                 error "$DIR/$tdir/$tfile timestamps changed" || true
3781
3782         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3783 }
3784
3785 test_36f() {
3786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3787
3788         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3789         subr_36fh "0x80000214"
3790 }
3791 run_test 36f "utime on file racing with OST BRW write =========="
3792
3793 test_36g() {
3794         remote_ost_nodsh && skip "remote OST with nodsh"
3795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3796         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3797                 skip "Need MDS version at least 2.12.51"
3798
3799         local fmd_max_age
3800         local fmd
3801         local facet="ost1"
3802         local tgt="obdfilter"
3803
3804         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3805
3806         test_mkdir $DIR/$tdir
3807         fmd_max_age=$(do_facet $facet \
3808                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3809                 head -n 1")
3810
3811         echo "FMD max age: ${fmd_max_age}s"
3812         touch $DIR/$tdir/$tfile
3813         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3814                 gawk '{cnt=cnt+$1}  END{print cnt}')
3815         echo "FMD before: $fmd"
3816         [[ $fmd == 0 ]] &&
3817                 error "FMD wasn't create by touch"
3818         sleep $((fmd_max_age + 12))
3819         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3820                 gawk '{cnt=cnt+$1}  END{print cnt}')
3821         echo "FMD after: $fmd"
3822         [[ $fmd == 0 ]] ||
3823                 error "FMD wasn't expired by ping"
3824 }
3825 run_test 36g "FMD cache expiry ====================="
3826
3827 test_36h() {
3828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3829
3830         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3831         subr_36fh "0x80000227"
3832 }
3833 run_test 36h "utime on file racing with OST BRW write =========="
3834
3835 test_36i() {
3836         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3837
3838         test_mkdir $DIR/$tdir
3839         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3840
3841         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3842         local new_mtime=$((mtime + 200))
3843
3844         #change Modify time of striped dir
3845         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3846                         error "change mtime failed"
3847
3848         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3849
3850         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3851 }
3852 run_test 36i "change mtime on striped directory"
3853
3854 # test_37 - duplicate with tests 32q 32r
3855
3856 test_38() {
3857         local file=$DIR/$tfile
3858         touch $file
3859         openfile -f O_DIRECTORY $file
3860         local RC=$?
3861         local ENOTDIR=20
3862         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3863         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3864 }
3865 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3866
3867 test_39a() { # was test_39
3868         touch $DIR/$tfile
3869         touch $DIR/${tfile}2
3870 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3871 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3872 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3873         sleep 2
3874         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3875         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3876                 echo "mtime"
3877                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3878                 echo "atime"
3879                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3880                 echo "ctime"
3881                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3882                 error "O_TRUNC didn't change timestamps"
3883         fi
3884 }
3885 run_test 39a "mtime changed on create"
3886
3887 test_39b() {
3888         test_mkdir -c1 $DIR/$tdir
3889         cp -p /etc/passwd $DIR/$tdir/fopen
3890         cp -p /etc/passwd $DIR/$tdir/flink
3891         cp -p /etc/passwd $DIR/$tdir/funlink
3892         cp -p /etc/passwd $DIR/$tdir/frename
3893         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3894
3895         sleep 1
3896         echo "aaaaaa" >> $DIR/$tdir/fopen
3897         echo "aaaaaa" >> $DIR/$tdir/flink
3898         echo "aaaaaa" >> $DIR/$tdir/funlink
3899         echo "aaaaaa" >> $DIR/$tdir/frename
3900
3901         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3902         local link_new=`stat -c %Y $DIR/$tdir/flink`
3903         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3904         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3905
3906         cat $DIR/$tdir/fopen > /dev/null
3907         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3908         rm -f $DIR/$tdir/funlink2
3909         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3910
3911         for (( i=0; i < 2; i++ )) ; do
3912                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3913                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3914                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3915                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3916
3917                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3918                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3919                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3920                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3921
3922                 cancel_lru_locks $OSC
3923                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3924         done
3925 }
3926 run_test 39b "mtime change on open, link, unlink, rename  ======"
3927
3928 # this should be set to past
3929 TEST_39_MTIME=`date -d "1 year ago" +%s`
3930
3931 # bug 11063
3932 test_39c() {
3933         touch $DIR1/$tfile
3934         sleep 2
3935         local mtime0=`stat -c %Y $DIR1/$tfile`
3936
3937         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3938         local mtime1=`stat -c %Y $DIR1/$tfile`
3939         [ "$mtime1" = $TEST_39_MTIME ] || \
3940                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3941
3942         local d1=`date +%s`
3943         echo hello >> $DIR1/$tfile
3944         local d2=`date +%s`
3945         local mtime2=`stat -c %Y $DIR1/$tfile`
3946         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3947                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3948
3949         mv $DIR1/$tfile $DIR1/$tfile-1
3950
3951         for (( i=0; i < 2; i++ )) ; do
3952                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3953                 [ "$mtime2" = "$mtime3" ] || \
3954                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3955
3956                 cancel_lru_locks $OSC
3957                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3958         done
3959 }
3960 run_test 39c "mtime change on rename ==========================="
3961
3962 # bug 21114
3963 test_39d() {
3964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3965
3966         touch $DIR1/$tfile
3967         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3968
3969         for (( i=0; i < 2; i++ )) ; do
3970                 local mtime=`stat -c %Y $DIR1/$tfile`
3971                 [ $mtime = $TEST_39_MTIME ] || \
3972                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3973
3974                 cancel_lru_locks $OSC
3975                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3976         done
3977 }
3978 run_test 39d "create, utime, stat =============================="
3979
3980 # bug 21114
3981 test_39e() {
3982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3983
3984         touch $DIR1/$tfile
3985         local mtime1=`stat -c %Y $DIR1/$tfile`
3986
3987         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3988
3989         for (( i=0; i < 2; i++ )) ; do
3990                 local mtime2=`stat -c %Y $DIR1/$tfile`
3991                 [ $mtime2 = $TEST_39_MTIME ] || \
3992                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3993
3994                 cancel_lru_locks $OSC
3995                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3996         done
3997 }
3998 run_test 39e "create, stat, utime, stat ========================"
3999
4000 # bug 21114
4001 test_39f() {
4002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4003
4004         touch $DIR1/$tfile
4005         mtime1=`stat -c %Y $DIR1/$tfile`
4006
4007         sleep 2
4008         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4009
4010         for (( i=0; i < 2; i++ )) ; do
4011                 local mtime2=`stat -c %Y $DIR1/$tfile`
4012                 [ $mtime2 = $TEST_39_MTIME ] || \
4013                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4014
4015                 cancel_lru_locks $OSC
4016                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4017         done
4018 }
4019 run_test 39f "create, stat, sleep, utime, stat ================="
4020
4021 # bug 11063
4022 test_39g() {
4023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4024
4025         echo hello >> $DIR1/$tfile
4026         local mtime1=`stat -c %Y $DIR1/$tfile`
4027
4028         sleep 2
4029         chmod o+r $DIR1/$tfile
4030
4031         for (( i=0; i < 2; i++ )) ; do
4032                 local mtime2=`stat -c %Y $DIR1/$tfile`
4033                 [ "$mtime1" = "$mtime2" ] || \
4034                         error "lost mtime: $mtime2, should be $mtime1"
4035
4036                 cancel_lru_locks $OSC
4037                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4038         done
4039 }
4040 run_test 39g "write, chmod, stat ==============================="
4041
4042 # bug 11063
4043 test_39h() {
4044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4045
4046         touch $DIR1/$tfile
4047         sleep 1
4048
4049         local d1=`date`
4050         echo hello >> $DIR1/$tfile
4051         local mtime1=`stat -c %Y $DIR1/$tfile`
4052
4053         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4054         local d2=`date`
4055         if [ "$d1" != "$d2" ]; then
4056                 echo "write and touch not within one second"
4057         else
4058                 for (( i=0; i < 2; i++ )) ; do
4059                         local mtime2=`stat -c %Y $DIR1/$tfile`
4060                         [ "$mtime2" = $TEST_39_MTIME ] || \
4061                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4062
4063                         cancel_lru_locks $OSC
4064                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4065                 done
4066         fi
4067 }
4068 run_test 39h "write, utime within one second, stat ============="
4069
4070 test_39i() {
4071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4072
4073         touch $DIR1/$tfile
4074         sleep 1
4075
4076         echo hello >> $DIR1/$tfile
4077         local mtime1=`stat -c %Y $DIR1/$tfile`
4078
4079         mv $DIR1/$tfile $DIR1/$tfile-1
4080
4081         for (( i=0; i < 2; i++ )) ; do
4082                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4083
4084                 [ "$mtime1" = "$mtime2" ] || \
4085                         error "lost mtime: $mtime2, should be $mtime1"
4086
4087                 cancel_lru_locks $OSC
4088                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4089         done
4090 }
4091 run_test 39i "write, rename, stat =============================="
4092
4093 test_39j() {
4094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4095
4096         start_full_debug_logging
4097         touch $DIR1/$tfile
4098         sleep 1
4099
4100         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4101         lctl set_param fail_loc=0x80000412
4102         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4103                 error "multiop failed"
4104         local multipid=$!
4105         local mtime1=`stat -c %Y $DIR1/$tfile`
4106
4107         mv $DIR1/$tfile $DIR1/$tfile-1
4108
4109         kill -USR1 $multipid
4110         wait $multipid || error "multiop close failed"
4111
4112         for (( i=0; i < 2; i++ )) ; do
4113                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4114                 [ "$mtime1" = "$mtime2" ] ||
4115                         error "mtime is lost on close: $mtime2, " \
4116                               "should be $mtime1"
4117
4118                 cancel_lru_locks $OSC
4119                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4120         done
4121         lctl set_param fail_loc=0
4122         stop_full_debug_logging
4123 }
4124 run_test 39j "write, rename, close, stat ======================="
4125
4126 test_39k() {
4127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4128
4129         touch $DIR1/$tfile
4130         sleep 1
4131
4132         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4133         local multipid=$!
4134         local mtime1=`stat -c %Y $DIR1/$tfile`
4135
4136         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4137
4138         kill -USR1 $multipid
4139         wait $multipid || error "multiop close failed"
4140
4141         for (( i=0; i < 2; i++ )) ; do
4142                 local mtime2=`stat -c %Y $DIR1/$tfile`
4143
4144                 [ "$mtime2" = $TEST_39_MTIME ] || \
4145                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4146
4147                 cancel_lru_locks osc
4148                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4149         done
4150 }
4151 run_test 39k "write, utime, close, stat ========================"
4152
4153 # this should be set to future
4154 TEST_39_ATIME=`date -d "1 year" +%s`
4155
4156 test_39l() {
4157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4158         remote_mds_nodsh && skip "remote MDS with nodsh"
4159
4160         local atime_diff=$(do_facet $SINGLEMDS \
4161                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4162         rm -rf $DIR/$tdir
4163         mkdir -p $DIR/$tdir
4164
4165         # test setting directory atime to future
4166         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4167         local atime=$(stat -c %X $DIR/$tdir)
4168         [ "$atime" = $TEST_39_ATIME ] ||
4169                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4170
4171         # test setting directory atime from future to now
4172         local now=$(date +%s)
4173         touch -a -d @$now $DIR/$tdir
4174
4175         atime=$(stat -c %X $DIR/$tdir)
4176         [ "$atime" -eq "$now"  ] ||
4177                 error "atime is not updated from future: $atime, $now"
4178
4179         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4180         sleep 3
4181
4182         # test setting directory atime when now > dir atime + atime_diff
4183         local d1=$(date +%s)
4184         ls $DIR/$tdir
4185         local d2=$(date +%s)
4186         cancel_lru_locks mdc
4187         atime=$(stat -c %X $DIR/$tdir)
4188         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4189                 error "atime is not updated  : $atime, should be $d2"
4190
4191         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4192         sleep 3
4193
4194         # test not setting directory atime when now < dir atime + atime_diff
4195         ls $DIR/$tdir
4196         cancel_lru_locks mdc
4197         atime=$(stat -c %X $DIR/$tdir)
4198         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4199                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4200
4201         do_facet $SINGLEMDS \
4202                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4203 }
4204 run_test 39l "directory atime update ==========================="
4205
4206 test_39m() {
4207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4208
4209         touch $DIR1/$tfile
4210         sleep 2
4211         local far_past_mtime=$(date -d "May 29 1953" +%s)
4212         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4213
4214         touch -m -d @$far_past_mtime $DIR1/$tfile
4215         touch -a -d @$far_past_atime $DIR1/$tfile
4216
4217         for (( i=0; i < 2; i++ )) ; do
4218                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4219                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4220                         error "atime or mtime set incorrectly"
4221
4222                 cancel_lru_locks $OSC
4223                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4224         done
4225 }
4226 run_test 39m "test atime and mtime before 1970"
4227
4228 test_39n() { # LU-3832
4229         remote_mds_nodsh && skip "remote MDS with nodsh"
4230
4231         local atime_diff=$(do_facet $SINGLEMDS \
4232                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4233         local atime0
4234         local atime1
4235         local atime2
4236
4237         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4238
4239         rm -rf $DIR/$tfile
4240         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4241         atime0=$(stat -c %X $DIR/$tfile)
4242
4243         sleep 5
4244         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4245         atime1=$(stat -c %X $DIR/$tfile)
4246
4247         sleep 5
4248         cancel_lru_locks mdc
4249         cancel_lru_locks osc
4250         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4251         atime2=$(stat -c %X $DIR/$tfile)
4252
4253         do_facet $SINGLEMDS \
4254                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4255
4256         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4257         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4258 }
4259 run_test 39n "check that O_NOATIME is honored"
4260
4261 test_39o() {
4262         TESTDIR=$DIR/$tdir/$tfile
4263         [ -e $TESTDIR ] && rm -rf $TESTDIR
4264         mkdir -p $TESTDIR
4265         cd $TESTDIR
4266         links1=2
4267         ls
4268         mkdir a b
4269         ls
4270         links2=$(stat -c %h .)
4271         [ $(($links1 + 2)) != $links2 ] &&
4272                 error "wrong links count $(($links1 + 2)) != $links2"
4273         rmdir b
4274         links3=$(stat -c %h .)
4275         [ $(($links1 + 1)) != $links3 ] &&
4276                 error "wrong links count $links1 != $links3"
4277         return 0
4278 }
4279 run_test 39o "directory cached attributes updated after create"
4280
4281 test_39p() {
4282         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4283
4284         local MDTIDX=1
4285         TESTDIR=$DIR/$tdir/$tdir
4286         [ -e $TESTDIR ] && rm -rf $TESTDIR
4287         test_mkdir -p $TESTDIR
4288         cd $TESTDIR
4289         links1=2
4290         ls
4291         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4292         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4293         ls
4294         links2=$(stat -c %h .)
4295         [ $(($links1 + 2)) != $links2 ] &&
4296                 error "wrong links count $(($links1 + 2)) != $links2"
4297         rmdir remote_dir2
4298         links3=$(stat -c %h .)
4299         [ $(($links1 + 1)) != $links3 ] &&
4300                 error "wrong links count $links1 != $links3"
4301         return 0
4302 }
4303 run_test 39p "remote directory cached attributes updated after create ========"
4304
4305
4306 test_39q() { # LU-8041
4307         local testdir=$DIR/$tdir
4308         mkdir -p $testdir
4309         multiop_bg_pause $testdir D_c || error "multiop failed"
4310         local multipid=$!
4311         cancel_lru_locks mdc
4312         kill -USR1 $multipid
4313         local atime=$(stat -c %X $testdir)
4314         [ "$atime" -ne 0 ] || error "atime is zero"
4315 }
4316 run_test 39q "close won't zero out atime"
4317
4318 test_40() {
4319         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4320         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4321                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4322         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4323                 error "$tfile is not 4096 bytes in size"
4324 }
4325 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4326
4327 test_41() {
4328         # bug 1553
4329         small_write $DIR/f41 18
4330 }
4331 run_test 41 "test small file write + fstat ====================="
4332
4333 count_ost_writes() {
4334         lctl get_param -n ${OSC}.*.stats |
4335                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4336                         END { printf("%0.0f", writes) }'
4337 }
4338
4339 # decent default
4340 WRITEBACK_SAVE=500
4341 DIRTY_RATIO_SAVE=40
4342 MAX_DIRTY_RATIO=50
4343 BG_DIRTY_RATIO_SAVE=10
4344 MAX_BG_DIRTY_RATIO=25
4345
4346 start_writeback() {
4347         trap 0
4348         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4349         # dirty_ratio, dirty_background_ratio
4350         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4351                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4352                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4353                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4354         else
4355                 # if file not here, we are a 2.4 kernel
4356                 kill -CONT `pidof kupdated`
4357         fi
4358 }
4359
4360 stop_writeback() {
4361         # setup the trap first, so someone cannot exit the test at the
4362         # exact wrong time and mess up a machine
4363         trap start_writeback EXIT
4364         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4365         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4366                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4367                 sysctl -w vm.dirty_writeback_centisecs=0
4368                 sysctl -w vm.dirty_writeback_centisecs=0
4369                 # save and increase /proc/sys/vm/dirty_ratio
4370                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4371                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4372                 # save and increase /proc/sys/vm/dirty_background_ratio
4373                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4374                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4375         else
4376                 # if file not here, we are a 2.4 kernel
4377                 kill -STOP `pidof kupdated`
4378         fi
4379 }
4380
4381 # ensure that all stripes have some grant before we test client-side cache
4382 setup_test42() {
4383         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4384                 dd if=/dev/zero of=$i bs=4k count=1
4385                 rm $i
4386         done
4387 }
4388
4389 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4390 # file truncation, and file removal.
4391 test_42a() {
4392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4393
4394         setup_test42
4395         cancel_lru_locks $OSC
4396         stop_writeback
4397         sync; sleep 1; sync # just to be safe
4398         BEFOREWRITES=`count_ost_writes`
4399         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4400         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4401         AFTERWRITES=`count_ost_writes`
4402         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4403                 error "$BEFOREWRITES < $AFTERWRITES"
4404         start_writeback
4405 }
4406 run_test 42a "ensure that we don't flush on close"
4407
4408 test_42b() {
4409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4410
4411         setup_test42
4412         cancel_lru_locks $OSC
4413         stop_writeback
4414         sync
4415         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4416         BEFOREWRITES=$(count_ost_writes)
4417         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4418         AFTERWRITES=$(count_ost_writes)
4419         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4420                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4421         fi
4422         BEFOREWRITES=$(count_ost_writes)
4423         sync || error "sync: $?"
4424         AFTERWRITES=$(count_ost_writes)
4425         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4426                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4427         fi
4428         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4429         start_writeback
4430         return 0
4431 }
4432 run_test 42b "test destroy of file with cached dirty data ======"
4433
4434 # if these tests just want to test the effect of truncation,
4435 # they have to be very careful.  consider:
4436 # - the first open gets a {0,EOF}PR lock
4437 # - the first write conflicts and gets a {0, count-1}PW
4438 # - the rest of the writes are under {count,EOF}PW
4439 # - the open for truncate tries to match a {0,EOF}PR
4440 #   for the filesize and cancels the PWs.
4441 # any number of fixes (don't get {0,EOF} on open, match
4442 # composite locks, do smarter file size management) fix
4443 # this, but for now we want these tests to verify that
4444 # the cancellation with truncate intent works, so we
4445 # start the file with a full-file pw lock to match against
4446 # until the truncate.
4447 trunc_test() {
4448         test=$1
4449         file=$DIR/$test
4450         offset=$2
4451         cancel_lru_locks $OSC
4452         stop_writeback
4453         # prime the file with 0,EOF PW to match
4454         touch $file
4455         $TRUNCATE $file 0
4456         sync; sync
4457         # now the real test..
4458         dd if=/dev/zero of=$file bs=1024 count=100
4459         BEFOREWRITES=`count_ost_writes`
4460         $TRUNCATE $file $offset
4461         cancel_lru_locks $OSC
4462         AFTERWRITES=`count_ost_writes`
4463         start_writeback
4464 }
4465
4466 test_42c() {
4467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4468
4469         trunc_test 42c 1024
4470         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4471                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4472         rm $file
4473 }
4474 run_test 42c "test partial truncate of file with cached dirty data"
4475
4476 test_42d() {
4477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4478
4479         trunc_test 42d 0
4480         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4481                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4482         rm $file
4483 }
4484 run_test 42d "test complete truncate of file with cached dirty data"
4485
4486 test_42e() { # bug22074
4487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4488
4489         local TDIR=$DIR/${tdir}e
4490         local pages=16 # hardcoded 16 pages, don't change it.
4491         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4492         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4493         local max_dirty_mb
4494         local warmup_files
4495
4496         test_mkdir $DIR/${tdir}e
4497         $LFS setstripe -c 1 $TDIR
4498         createmany -o $TDIR/f $files
4499
4500         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4501
4502         # we assume that with $OSTCOUNT files, at least one of them will
4503         # be allocated on OST0.
4504         warmup_files=$((OSTCOUNT * max_dirty_mb))
4505         createmany -o $TDIR/w $warmup_files
4506
4507         # write a large amount of data into one file and sync, to get good
4508         # avail_grant number from OST.
4509         for ((i=0; i<$warmup_files; i++)); do
4510                 idx=$($LFS getstripe -i $TDIR/w$i)
4511                 [ $idx -ne 0 ] && continue
4512                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4513                 break
4514         done
4515         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4516         sync
4517         $LCTL get_param $proc_osc0/cur_dirty_bytes
4518         $LCTL get_param $proc_osc0/cur_grant_bytes
4519
4520         # create as much dirty pages as we can while not to trigger the actual
4521         # RPCs directly. but depends on the env, VFS may trigger flush during this
4522         # period, hopefully we are good.
4523         for ((i=0; i<$warmup_files; i++)); do
4524                 idx=$($LFS getstripe -i $TDIR/w$i)
4525                 [ $idx -ne 0 ] && continue
4526                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4527         done
4528         $LCTL get_param $proc_osc0/cur_dirty_bytes
4529         $LCTL get_param $proc_osc0/cur_grant_bytes
4530
4531         # perform the real test
4532         $LCTL set_param $proc_osc0/rpc_stats 0
4533         for ((;i<$files; i++)); do
4534                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4535                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4536         done
4537         sync
4538         $LCTL get_param $proc_osc0/rpc_stats
4539
4540         local percent=0
4541         local have_ppr=false
4542         $LCTL get_param $proc_osc0/rpc_stats |
4543                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4544                         # skip lines until we are at the RPC histogram data
4545                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4546                         $have_ppr || continue
4547
4548                         # we only want the percent stat for < 16 pages
4549                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4550
4551                         percent=$((percent + WPCT))
4552                         if [[ $percent -gt 15 ]]; then
4553                                 error "less than 16-pages write RPCs" \
4554                                       "$percent% > 15%"
4555                                 break
4556                         fi
4557                 done
4558         rm -rf $TDIR
4559 }
4560 run_test 42e "verify sub-RPC writes are not done synchronously"
4561
4562 test_43A() { # was test_43
4563         test_mkdir $DIR/$tdir
4564         cp -p /bin/ls $DIR/$tdir/$tfile
4565         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4566         pid=$!
4567         # give multiop a chance to open
4568         sleep 1
4569
4570         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4571         kill -USR1 $pid
4572 }
4573 run_test 43A "execution of file opened for write should return -ETXTBSY"
4574
4575 test_43a() {
4576         test_mkdir $DIR/$tdir
4577         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4578         $DIR/$tdir/sleep 60 &
4579         SLEEP_PID=$!
4580         # Make sure exec of $tdir/sleep wins race with truncate
4581         sleep 1
4582         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4583         kill $SLEEP_PID
4584 }
4585 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4586
4587 test_43b() {
4588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4589
4590         test_mkdir $DIR/$tdir
4591         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4592         $DIR/$tdir/sleep 60 &
4593         SLEEP_PID=$!
4594         # Make sure exec of $tdir/sleep wins race with truncate
4595         sleep 1
4596         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4597         kill $SLEEP_PID
4598 }
4599 run_test 43b "truncate of file being executed should return -ETXTBSY"
4600
4601 test_43c() {
4602         local testdir="$DIR/$tdir"
4603         test_mkdir $testdir
4604         cp $SHELL $testdir/
4605         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4606                 ( cd $testdir && md5sum -c )
4607 }
4608 run_test 43c "md5sum of copy into lustre"
4609
4610 test_44A() { # was test_44
4611         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4612
4613         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4614         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4615 }
4616 run_test 44A "zero length read from a sparse stripe"
4617
4618 test_44a() {
4619         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4620                 awk '{ print $2 }')
4621         [ -z "$nstripe" ] && skip "can't get stripe info"
4622         [[ $nstripe -gt $OSTCOUNT ]] &&
4623                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4624
4625         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4626                 awk '{ print $2 }')
4627         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4628                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4629                         awk '{ print $2 }')
4630         fi
4631
4632         OFFSETS="0 $((stride/2)) $((stride-1))"
4633         for offset in $OFFSETS; do
4634                 for i in $(seq 0 $((nstripe-1))); do
4635                         local GLOBALOFFSETS=""
4636                         # size in Bytes
4637                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4638                         local myfn=$DIR/d44a-$size
4639                         echo "--------writing $myfn at $size"
4640                         ll_sparseness_write $myfn $size ||
4641                                 error "ll_sparseness_write"
4642                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4643                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4644                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4645
4646                         for j in $(seq 0 $((nstripe-1))); do
4647                                 # size in Bytes
4648                                 size=$((((j + $nstripe )*$stride + $offset)))
4649                                 ll_sparseness_write $myfn $size ||
4650                                         error "ll_sparseness_write"
4651                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4652                         done
4653                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4654                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4655                         rm -f $myfn
4656                 done
4657         done
4658 }
4659 run_test 44a "test sparse pwrite ==============================="
4660
4661 dirty_osc_total() {
4662         tot=0
4663         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4664                 tot=$(($tot + $d))
4665         done
4666         echo $tot
4667 }
4668 do_dirty_record() {
4669         before=`dirty_osc_total`
4670         echo executing "\"$*\""
4671         eval $*
4672         after=`dirty_osc_total`
4673         echo before $before, after $after
4674 }
4675 test_45() {
4676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4677
4678         f="$DIR/f45"
4679         # Obtain grants from OST if it supports it
4680         echo blah > ${f}_grant
4681         stop_writeback
4682         sync
4683         do_dirty_record "echo blah > $f"
4684         [[ $before -eq $after ]] && error "write wasn't cached"
4685         do_dirty_record "> $f"
4686         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4687         do_dirty_record "echo blah > $f"
4688         [[ $before -eq $after ]] && error "write wasn't cached"
4689         do_dirty_record "sync"
4690         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4691         do_dirty_record "echo blah > $f"
4692         [[ $before -eq $after ]] && error "write wasn't cached"
4693         do_dirty_record "cancel_lru_locks osc"
4694         [[ $before -gt $after ]] ||
4695                 error "lock cancellation didn't lower dirty count"
4696         start_writeback
4697 }
4698 run_test 45 "osc io page accounting ============================"
4699
4700 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4701 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4702 # objects offset and an assert hit when an rpc was built with 1023's mapped
4703 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4704 test_46() {
4705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4706
4707         f="$DIR/f46"
4708         stop_writeback
4709         sync
4710         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4711         sync
4712         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4713         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4714         sync
4715         start_writeback
4716 }
4717 run_test 46 "dirtying a previously written page ================"
4718
4719 # test_47 is removed "Device nodes check" is moved to test_28
4720
4721 test_48a() { # bug 2399
4722         [ "$mds1_FSTYPE" = "zfs" ] &&
4723         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4724                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4725
4726         test_mkdir $DIR/$tdir
4727         cd $DIR/$tdir
4728         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4729         test_mkdir $DIR/$tdir
4730         touch foo || error "'touch foo' failed after recreating cwd"
4731         test_mkdir bar
4732         touch .foo || error "'touch .foo' failed after recreating cwd"
4733         test_mkdir .bar
4734         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4735         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4736         cd . || error "'cd .' failed after recreating cwd"
4737         mkdir . && error "'mkdir .' worked after recreating cwd"
4738         rmdir . && error "'rmdir .' worked after recreating cwd"
4739         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4740         cd .. || error "'cd ..' failed after recreating cwd"
4741 }
4742 run_test 48a "Access renamed working dir (should return errors)="
4743
4744 test_48b() { # bug 2399
4745         rm -rf $DIR/$tdir
4746         test_mkdir $DIR/$tdir
4747         cd $DIR/$tdir
4748         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4749         touch foo && error "'touch foo' worked after removing cwd"
4750         mkdir foo && error "'mkdir foo' worked after removing cwd"
4751         touch .foo && error "'touch .foo' worked after removing cwd"
4752         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4753         ls . > /dev/null && error "'ls .' worked after removing cwd"
4754         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4755         mkdir . && error "'mkdir .' worked after removing cwd"
4756         rmdir . && error "'rmdir .' worked after removing cwd"
4757         ln -s . foo && error "'ln -s .' worked after removing cwd"
4758         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4759 }
4760 run_test 48b "Access removed working dir (should return errors)="
4761
4762 test_48c() { # bug 2350
4763         #lctl set_param debug=-1
4764         #set -vx
4765         rm -rf $DIR/$tdir
4766         test_mkdir -p $DIR/$tdir/dir
4767         cd $DIR/$tdir/dir
4768         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4769         $TRACE touch foo && error "touch foo worked after removing cwd"
4770         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4771         touch .foo && error "touch .foo worked after removing cwd"
4772         mkdir .foo && error "mkdir .foo worked after removing cwd"
4773         $TRACE ls . && error "'ls .' worked after removing cwd"
4774         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4775         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4776         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4777         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4778         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4779 }
4780 run_test 48c "Access removed working subdir (should return errors)"
4781
4782 test_48d() { # bug 2350
4783         #lctl set_param debug=-1
4784         #set -vx
4785         rm -rf $DIR/$tdir
4786         test_mkdir -p $DIR/$tdir/dir
4787         cd $DIR/$tdir/dir
4788         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4789         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4790         $TRACE touch foo && error "'touch foo' worked after removing parent"
4791         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4792         touch .foo && error "'touch .foo' worked after removing parent"
4793         mkdir .foo && error "mkdir .foo worked after removing parent"
4794         $TRACE ls . && error "'ls .' worked after removing parent"
4795         $TRACE ls .. && error "'ls ..' worked after removing parent"
4796         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4797         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4798         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4799         true
4800 }
4801 run_test 48d "Access removed parent subdir (should return errors)"
4802
4803 test_48e() { # bug 4134
4804         #lctl set_param debug=-1
4805         #set -vx
4806         rm -rf $DIR/$tdir
4807         test_mkdir -p $DIR/$tdir/dir
4808         cd $DIR/$tdir/dir
4809         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4810         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4811         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4812         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4813         # On a buggy kernel addition of "touch foo" after cd .. will
4814         # produce kernel oops in lookup_hash_it
4815         touch ../foo && error "'cd ..' worked after recreate parent"
4816         cd $DIR
4817         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4818 }
4819 run_test 48e "Access to recreated parent subdir (should return errors)"
4820
4821 test_49() { # LU-1030
4822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4823         remote_ost_nodsh && skip "remote OST with nodsh"
4824
4825         # get ost1 size - lustre-OST0000
4826         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4827                 awk '{ print $4 }')
4828         # write 800M at maximum
4829         [[ $ost1_size -lt 2 ]] && ost1_size=2
4830         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4831
4832         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4833         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4834         local dd_pid=$!
4835
4836         # change max_pages_per_rpc while writing the file
4837         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4838         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4839         # loop until dd process exits
4840         while ps ax -opid | grep -wq $dd_pid; do
4841                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4842                 sleep $((RANDOM % 5 + 1))
4843         done
4844         # restore original max_pages_per_rpc
4845         $LCTL set_param $osc1_mppc=$orig_mppc
4846         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4847 }
4848 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4849
4850 test_50() {
4851         # bug 1485
4852         test_mkdir $DIR/$tdir
4853         cd $DIR/$tdir
4854         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4855 }
4856 run_test 50 "special situations: /proc symlinks  ==============="
4857
4858 test_51a() {    # was test_51
4859         # bug 1516 - create an empty entry right after ".." then split dir
4860         test_mkdir -c1 $DIR/$tdir
4861         touch $DIR/$tdir/foo
4862         $MCREATE $DIR/$tdir/bar
4863         rm $DIR/$tdir/foo
4864         createmany -m $DIR/$tdir/longfile 201
4865         FNUM=202
4866         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4867                 $MCREATE $DIR/$tdir/longfile$FNUM
4868                 FNUM=$(($FNUM + 1))
4869                 echo -n "+"
4870         done
4871         echo
4872         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4873 }
4874 run_test 51a "special situations: split htree with empty entry =="
4875
4876 cleanup_print_lfs_df () {
4877         trap 0
4878         $LFS df
4879         $LFS df -i
4880 }
4881
4882 test_51b() {
4883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4884
4885         local dir=$DIR/$tdir
4886         local nrdirs=$((65536 + 100))
4887
4888         # cleanup the directory
4889         rm -fr $dir
4890
4891         test_mkdir -c1 $dir
4892
4893         $LFS df
4894         $LFS df -i
4895         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4896         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4897         [[ $numfree -lt $nrdirs ]] &&
4898                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4899
4900         # need to check free space for the directories as well
4901         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4902         numfree=$(( blkfree / $(fs_inode_ksize) ))
4903         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4904
4905         trap cleanup_print_lfs_df EXIT
4906
4907         # create files
4908         createmany -d $dir/d $nrdirs || {
4909                 unlinkmany $dir/d $nrdirs
4910                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4911         }
4912
4913         # really created :
4914         nrdirs=$(ls -U $dir | wc -l)
4915
4916         # unlink all but 100 subdirectories, then check it still works
4917         local left=100
4918         local delete=$((nrdirs - left))
4919
4920         $LFS df
4921         $LFS df -i
4922
4923         # for ldiskfs the nlink count should be 1, but this is OSD specific
4924         # and so this is listed for informational purposes only
4925         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4926         unlinkmany -d $dir/d $delete ||
4927                 error "unlink of first $delete subdirs failed"
4928
4929         echo "nlink between: $(stat -c %h $dir)"
4930         local found=$(ls -U $dir | wc -l)
4931         [ $found -ne $left ] &&
4932                 error "can't find subdirs: found only $found, expected $left"
4933
4934         unlinkmany -d $dir/d $delete $left ||
4935                 error "unlink of second $left subdirs failed"
4936         # regardless of whether the backing filesystem tracks nlink accurately
4937         # or not, the nlink count shouldn't be more than "." and ".." here
4938         local after=$(stat -c %h $dir)
4939         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4940                 echo "nlink after: $after"
4941
4942         cleanup_print_lfs_df
4943 }
4944 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4945
4946 test_51d() {
4947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4948         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4949
4950         test_mkdir $DIR/$tdir
4951         createmany -o $DIR/$tdir/t- 1000
4952         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4953         for N in $(seq 0 $((OSTCOUNT - 1))); do
4954                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4955                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4956                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4957                         '($1 == '$N') { objs += 1 } \
4958                         END { printf("%0.0f", objs) }')
4959                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4960         done
4961         unlinkmany $DIR/$tdir/t- 1000
4962
4963         NLAST=0
4964         for N in $(seq 1 $((OSTCOUNT - 1))); do
4965                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4966                         error "OST $N has less objects vs OST $NLAST" \
4967                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4968                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4969                         error "OST $N has less objects vs OST $NLAST" \
4970                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4971
4972                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4973                         error "OST $N has less #0 objects vs OST $NLAST" \
4974                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4975                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4976                         error "OST $N has less #0 objects vs OST $NLAST" \
4977                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4978                 NLAST=$N
4979         done
4980         rm -f $TMP/$tfile
4981 }
4982 run_test 51d "check object distribution"
4983
4984 test_51e() {
4985         if [ "$mds1_FSTYPE" != ldiskfs ]; then
4986                 skip_env "ldiskfs only test"
4987         fi
4988
4989         test_mkdir -c1 $DIR/$tdir
4990         test_mkdir -c1 $DIR/$tdir/d0
4991
4992         touch $DIR/$tdir/d0/foo
4993         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
4994                 error "file exceed 65000 nlink limit!"
4995         unlinkmany $DIR/$tdir/d0/f- 65001
4996         return 0
4997 }
4998 run_test 51e "check file nlink limit"
4999
5000 test_51f() {
5001         test_mkdir $DIR/$tdir
5002
5003         local max=100000
5004         local ulimit_old=$(ulimit -n)
5005         local spare=20 # number of spare fd's for scripts/libraries, etc.
5006         local mdt=$($LFS getstripe -m $DIR/$tdir)
5007         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5008
5009         echo "MDT$mdt numfree=$numfree, max=$max"
5010         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5011         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5012                 while ! ulimit -n $((numfree + spare)); do
5013                         numfree=$((numfree * 3 / 4))
5014                 done
5015                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5016         else
5017                 echo "left ulimit at $ulimit_old"
5018         fi
5019
5020         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5021                 unlinkmany $DIR/$tdir/f $numfree
5022                 error "create+open $numfree files in $DIR/$tdir failed"
5023         }
5024         ulimit -n $ulimit_old
5025
5026         # if createmany exits at 120s there will be fewer than $numfree files
5027         unlinkmany $DIR/$tdir/f $numfree || true
5028 }
5029 run_test 51f "check many open files limit"
5030
5031 test_52a() {
5032         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5033         test_mkdir $DIR/$tdir
5034         touch $DIR/$tdir/foo
5035         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5036         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5037         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5038         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5039         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5040                                         error "link worked"
5041         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5042         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5043         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5044                                                      error "lsattr"
5045         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5046         cp -r $DIR/$tdir $TMP/
5047         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5048 }
5049 run_test 52a "append-only flag test (should return errors)"
5050
5051 test_52b() {
5052         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5053         test_mkdir $DIR/$tdir
5054         touch $DIR/$tdir/foo
5055         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5056         cat test > $DIR/$tdir/foo && error "cat test worked"
5057         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5058         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5059         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5060                                         error "link worked"
5061         echo foo >> $DIR/$tdir/foo && error "echo worked"
5062         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5063         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5064         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5065         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5066                                                         error "lsattr"
5067         chattr -i $DIR/$tdir/foo || error "chattr failed"
5068
5069         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5070 }
5071 run_test 52b "immutable flag test (should return errors) ======="
5072
5073 test_53() {
5074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5075         remote_mds_nodsh && skip "remote MDS with nodsh"
5076         remote_ost_nodsh && skip "remote OST with nodsh"
5077
5078         local param
5079         local param_seq
5080         local ostname
5081         local mds_last
5082         local mds_last_seq
5083         local ost_last
5084         local ost_last_seq
5085         local ost_last_id
5086         local ostnum
5087         local node
5088         local found=false
5089         local support_last_seq=true
5090
5091         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5092                 support_last_seq=false
5093
5094         # only test MDT0000
5095         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5096         local value
5097         for value in $(do_facet $SINGLEMDS \
5098                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5099                 param=$(echo ${value[0]} | cut -d "=" -f1)
5100                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5101
5102                 if $support_last_seq; then
5103                         param_seq=$(echo $param |
5104                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5105                         mds_last_seq=$(do_facet $SINGLEMDS \
5106                                        $LCTL get_param -n $param_seq)
5107                 fi
5108                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5109
5110                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5111                 node=$(facet_active_host ost$((ostnum+1)))
5112                 param="obdfilter.$ostname.last_id"
5113                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5114                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5115                         ost_last_id=$ost_last
5116
5117                         if $support_last_seq; then
5118                                 ost_last_id=$(echo $ost_last |
5119                                               awk -F':' '{print $2}' |
5120                                               sed -e "s/^0x//g")
5121                                 ost_last_seq=$(echo $ost_last |
5122                                                awk -F':' '{print $1}')
5123                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5124                         fi
5125
5126                         if [[ $ost_last_id != $mds_last ]]; then
5127                                 error "$ost_last_id != $mds_last"
5128                         else
5129                                 found=true
5130                                 break
5131                         fi
5132                 done
5133         done
5134         $found || error "can not match last_seq/last_id for $mdtosc"
5135         return 0
5136 }
5137 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5138
5139 test_54a() {
5140         perl -MSocket -e ';' || skip "no Socket perl module installed"
5141
5142         $SOCKETSERVER $DIR/socket ||
5143                 error "$SOCKETSERVER $DIR/socket failed: $?"
5144         $SOCKETCLIENT $DIR/socket ||
5145                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5146         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5147 }
5148 run_test 54a "unix domain socket test =========================="
5149
5150 test_54b() {
5151         f="$DIR/f54b"
5152         mknod $f c 1 3
5153         chmod 0666 $f
5154         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5155 }
5156 run_test 54b "char device works in lustre ======================"
5157
5158 find_loop_dev() {
5159         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5160         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5161         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5162
5163         for i in $(seq 3 7); do
5164                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5165                 LOOPDEV=$LOOPBASE$i
5166                 LOOPNUM=$i
5167                 break
5168         done
5169 }
5170
5171 cleanup_54c() {
5172         local rc=0
5173         loopdev="$DIR/loop54c"
5174
5175         trap 0
5176         $UMOUNT $DIR/$tdir || rc=$?
5177         losetup -d $loopdev || true
5178         losetup -d $LOOPDEV || true
5179         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5180         return $rc
5181 }
5182
5183 test_54c() {
5184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5185
5186         loopdev="$DIR/loop54c"
5187
5188         find_loop_dev
5189         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5190         trap cleanup_54c EXIT
5191         mknod $loopdev b 7 $LOOPNUM
5192         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5193         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5194         losetup $loopdev $DIR/$tfile ||
5195                 error "can't set up $loopdev for $DIR/$tfile"
5196         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5197         test_mkdir $DIR/$tdir
5198         mount -t ext2 $loopdev $DIR/$tdir ||
5199                 error "error mounting $loopdev on $DIR/$tdir"
5200         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5201                 error "dd write"
5202         df $DIR/$tdir
5203         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5204                 error "dd read"
5205         cleanup_54c
5206 }
5207 run_test 54c "block device works in lustre ====================="
5208
5209 test_54d() {
5210         f="$DIR/f54d"
5211         string="aaaaaa"
5212         mknod $f p
5213         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5214 }
5215 run_test 54d "fifo device works in lustre ======================"
5216
5217 test_54e() {
5218         f="$DIR/f54e"
5219         string="aaaaaa"
5220         cp -aL /dev/console $f
5221         echo $string > $f || error "echo $string to $f failed"
5222 }
5223 run_test 54e "console/tty device works in lustre ======================"
5224
5225 test_56a() {
5226         local numfiles=3
5227         local dir=$DIR/$tdir
5228
5229         rm -rf $dir
5230         test_mkdir -p $dir/dir
5231         for i in $(seq $numfiles); do
5232                 touch $dir/file$i
5233                 touch $dir/dir/file$i
5234         done
5235
5236         local numcomp=$($LFS getstripe --component-count $dir)
5237
5238         [[ $numcomp == 0 ]] && numcomp=1
5239
5240         # test lfs getstripe with --recursive
5241         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5242
5243         [[ $filenum -eq $((numfiles * 2)) ]] ||
5244                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5245         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5246         [[ $filenum -eq $numfiles ]] ||
5247                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5248         echo "$LFS getstripe showed obdidx or l_ost_idx"
5249
5250         # test lfs getstripe with file instead of dir
5251         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5252         [[ $filenum -eq 1 ]] ||
5253                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5254         echo "$LFS getstripe file1 passed"
5255
5256         #test lfs getstripe with --verbose
5257         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5258         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5259                 error "$LFS getstripe --verbose $dir: "\
5260                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5261         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5262                 error "$LFS getstripe $dir: showed lmm_magic"
5263
5264         #test lfs getstripe with -v prints lmm_fid
5265         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5266         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5267                 error "$LFS getstripe -v $dir: "\
5268                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5269         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5270                 error "$LFS getstripe $dir: showed lmm_fid by default"
5271         echo "$LFS getstripe --verbose passed"
5272
5273         #check for FID information
5274         local fid1=$($LFS getstripe --fid $dir/file1)
5275         local fid2=$($LFS getstripe --verbose $dir/file1 |
5276                      awk '/lmm_fid: / { print $2; exit; }')
5277         local fid3=$($LFS path2fid $dir/file1)
5278
5279         [ "$fid1" != "$fid2" ] &&
5280                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5281         [ "$fid1" != "$fid3" ] &&
5282                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5283         echo "$LFS getstripe --fid passed"
5284
5285         #test lfs getstripe with --obd
5286         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5287                 error "$LFS getstripe --obd wrong_uuid: should return error"
5288
5289         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5290
5291         local ostidx=1
5292         local obduuid=$(ostuuid_from_index $ostidx)
5293         local found=$($LFS getstripe -r --obd $obduuid $dir |
5294                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5295
5296         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5297         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5298                 ((filenum--))
5299         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5300                 ((filenum--))
5301
5302         [[ $found -eq $filenum ]] ||
5303                 error "$LFS getstripe --obd: found $found expect $filenum"
5304         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5305                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5306                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5307                 error "$LFS getstripe --obd: should not show file on other obd"
5308         echo "$LFS getstripe --obd passed"
5309 }
5310 run_test 56a "check $LFS getstripe"
5311
5312 test_56b() {
5313         local dir=$DIR/$tdir
5314         local numdirs=3
5315
5316         test_mkdir $dir
5317         for i in $(seq $numdirs); do
5318                 test_mkdir $dir/dir$i
5319         done
5320
5321         # test lfs getdirstripe default mode is non-recursion, which is
5322         # different from lfs getstripe
5323         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5324
5325         [[ $dircnt -eq 1 ]] ||
5326                 error "$LFS getdirstripe: found $dircnt, not 1"
5327         dircnt=$($LFS getdirstripe --recursive $dir |
5328                 grep -c lmv_stripe_count)
5329         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5330                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5331 }
5332 run_test 56b "check $LFS getdirstripe"
5333
5334 test_56c() {
5335         remote_ost_nodsh && skip "remote OST with nodsh"
5336
5337         local ost_idx=0
5338         local ost_name=$(ostname_from_index $ost_idx)
5339         local old_status=$(ost_dev_status $ost_idx)
5340
5341         [[ -z "$old_status" ]] ||
5342                 skip_env "OST $ost_name is in $old_status status"
5343
5344         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5345         sleep_maxage
5346
5347         local new_status=$(ost_dev_status $ost_idx)
5348
5349         [[ "$new_status" = "D" ]] ||
5350                 error "OST $ost_name is in status of '$new_status', not 'D'"
5351
5352         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5353         sleep_maxage
5354
5355         new_status=$(ost_dev_status $ost_idx)
5356         [[ -z "$new_status" ]] ||
5357                 error "OST $ost_name is in status of '$new_status', not ''"
5358 }
5359 run_test 56c "check 'lfs df' showing device status"
5360
5361 NUMFILES=3
5362 NUMDIRS=3
5363 setup_56() {
5364         local local_tdir="$1"
5365         local local_numfiles="$2"
5366         local local_numdirs="$3"
5367         local dir_params="$4"
5368         local dir_stripe_params="$5"
5369
5370         if [ ! -d "$local_tdir" ] ; then
5371                 test_mkdir -p $dir_stripe_params $local_tdir
5372                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5373                 for i in $(seq $local_numfiles) ; do
5374                         touch $local_tdir/file$i
5375                 done
5376                 for i in $(seq $local_numdirs) ; do
5377                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5378                         for j in $(seq $local_numfiles) ; do
5379                                 touch $local_tdir/dir$i/file$j
5380                         done
5381                 done
5382         fi
5383 }
5384
5385 setup_56_special() {
5386         local local_tdir=$1
5387         local local_numfiles=$2
5388         local local_numdirs=$3
5389
5390         setup_56 $local_tdir $local_numfiles $local_numdirs
5391
5392         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5393                 for i in $(seq $local_numfiles) ; do
5394                         mknod $local_tdir/loop${i}b b 7 $i
5395                         mknod $local_tdir/null${i}c c 1 3
5396                         ln -s $local_tdir/file1 $local_tdir/link${i}
5397                 done
5398                 for i in $(seq $local_numdirs) ; do
5399                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5400                         mknod $local_tdir/dir$i/null${i}c c 1 3
5401                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5402                 done
5403         fi
5404 }
5405
5406 test_56g() {
5407         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5408         local expected=$(($NUMDIRS + 2))
5409
5410         setup_56 $dir $NUMFILES $NUMDIRS
5411
5412         # test lfs find with -name
5413         for i in $(seq $NUMFILES) ; do
5414                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5415
5416                 [ $nums -eq $expected ] ||
5417                         error "lfs find -name '*$i' $dir wrong: "\
5418                               "found $nums, expected $expected"
5419         done
5420 }
5421 run_test 56g "check lfs find -name"
5422
5423 test_56h() {
5424         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5425         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5426
5427         setup_56 $dir $NUMFILES $NUMDIRS
5428
5429         # test lfs find with ! -name
5430         for i in $(seq $NUMFILES) ; do
5431                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5432
5433                 [ $nums -eq $expected ] ||
5434                         error "lfs find ! -name '*$i' $dir wrong: "\
5435                               "found $nums, expected $expected"
5436         done
5437 }
5438 run_test 56h "check lfs find ! -name"
5439
5440 test_56i() {
5441         local dir=$DIR/$tdir
5442
5443         test_mkdir $dir
5444
5445         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5446         local out=$($cmd)
5447
5448         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5449 }
5450 run_test 56i "check 'lfs find -ost UUID' skips directories"
5451
5452 test_56j() {
5453         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5454
5455         setup_56_special $dir $NUMFILES $NUMDIRS
5456
5457         local expected=$((NUMDIRS + 1))
5458         local cmd="$LFS find -type d $dir"
5459         local nums=$($cmd | wc -l)
5460
5461         [ $nums -eq $expected ] ||
5462                 error "'$cmd' wrong: found $nums, expected $expected"
5463 }
5464 run_test 56j "check lfs find -type d"
5465
5466 test_56k() {
5467         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5468
5469         setup_56_special $dir $NUMFILES $NUMDIRS
5470
5471         local expected=$(((NUMDIRS + 1) * NUMFILES))
5472         local cmd="$LFS find -type f $dir"
5473         local nums=$($cmd | wc -l)
5474
5475         [ $nums -eq $expected ] ||
5476                 error "'$cmd' wrong: found $nums, expected $expected"
5477 }
5478 run_test 56k "check lfs find -type f"
5479
5480 test_56l() {
5481         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5482
5483         setup_56_special $dir $NUMFILES $NUMDIRS
5484
5485         local expected=$((NUMDIRS + NUMFILES))
5486         local cmd="$LFS find -type b $dir"
5487         local nums=$($cmd | wc -l)
5488
5489         [ $nums -eq $expected ] ||
5490                 error "'$cmd' wrong: found $nums, expected $expected"
5491 }
5492 run_test 56l "check lfs find -type b"
5493
5494 test_56m() {
5495         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5496
5497         setup_56_special $dir $NUMFILES $NUMDIRS
5498
5499         local expected=$((NUMDIRS + NUMFILES))
5500         local cmd="$LFS find -type c $dir"
5501         local nums=$($cmd | wc -l)
5502         [ $nums -eq $expected ] ||
5503                 error "'$cmd' wrong: found $nums, expected $expected"
5504 }
5505 run_test 56m "check lfs find -type c"
5506
5507 test_56n() {
5508         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5509         setup_56_special $dir $NUMFILES $NUMDIRS
5510
5511         local expected=$((NUMDIRS + NUMFILES))
5512         local cmd="$LFS find -type l $dir"
5513         local nums=$($cmd | wc -l)
5514
5515         [ $nums -eq $expected ] ||
5516                 error "'$cmd' wrong: found $nums, expected $expected"
5517 }
5518 run_test 56n "check lfs find -type l"
5519
5520 test_56o() {
5521         local dir=$DIR/$tdir
5522
5523         setup_56 $dir $NUMFILES $NUMDIRS
5524         utime $dir/file1 > /dev/null || error "utime (1)"
5525         utime $dir/file2 > /dev/null || error "utime (2)"
5526         utime $dir/dir1 > /dev/null || error "utime (3)"
5527         utime $dir/dir2 > /dev/null || error "utime (4)"
5528         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5529         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5530
5531         local expected=4
5532         local nums=$($LFS find -mtime +0 $dir | wc -l)
5533
5534         [ $nums -eq $expected ] ||
5535                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5536
5537         expected=12
5538         cmd="$LFS find -mtime 0 $dir"
5539         nums=$($cmd | wc -l)
5540         [ $nums -eq $expected ] ||
5541                 error "'$cmd' wrong: found $nums, expected $expected"
5542 }
5543 run_test 56o "check lfs find -mtime for old files"
5544
5545 test_56ob() {
5546         local dir=$DIR/$tdir
5547         local expected=1
5548         local count=0
5549
5550         # just to make sure there is something that won't be found
5551         test_mkdir $dir
5552         touch $dir/$tfile.now
5553
5554         for age in year week day hour min; do
5555                 count=$((count + 1))
5556
5557                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5558                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5559                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5560
5561                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5562                 local nums=$($cmd | wc -l)
5563                 [ $nums -eq $expected ] ||
5564                         error "'$cmd' wrong: found $nums, expected $expected"
5565
5566                 cmd="$LFS find $dir -atime $count${age:0:1}"
5567                 nums=$($cmd | wc -l)
5568                 [ $nums -eq $expected ] ||
5569                         error "'$cmd' wrong: found $nums, expected $expected"
5570         done
5571
5572         sleep 2
5573         cmd="$LFS find $dir -ctime +1s -type f"
5574         nums=$($cmd | wc -l)
5575         (( $nums == $count * 2 + 1)) ||
5576                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5577 }
5578 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5579
5580 test_56p() {
5581         [ $RUNAS_ID -eq $UID ] &&
5582                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5583
5584         local dir=$DIR/$tdir
5585
5586         setup_56 $dir $NUMFILES $NUMDIRS
5587         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5588
5589         local expected=$NUMFILES
5590         local cmd="$LFS find -uid $RUNAS_ID $dir"
5591         local nums=$($cmd | wc -l)
5592
5593         [ $nums -eq $expected ] ||
5594                 error "'$cmd' wrong: found $nums, expected $expected"
5595
5596         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5597         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5598         nums=$($cmd | wc -l)
5599         [ $nums -eq $expected ] ||
5600                 error "'$cmd' wrong: found $nums, expected $expected"
5601 }
5602 run_test 56p "check lfs find -uid and ! -uid"
5603
5604 test_56q() {
5605         [ $RUNAS_ID -eq $UID ] &&
5606                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5607
5608         local dir=$DIR/$tdir
5609
5610         setup_56 $dir $NUMFILES $NUMDIRS
5611         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5612
5613         local expected=$NUMFILES
5614         local cmd="$LFS find -gid $RUNAS_GID $dir"
5615         local nums=$($cmd | wc -l)
5616
5617         [ $nums -eq $expected ] ||
5618                 error "'$cmd' wrong: found $nums, expected $expected"
5619
5620         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5621         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5622         nums=$($cmd | wc -l)
5623         [ $nums -eq $expected ] ||
5624                 error "'$cmd' wrong: found $nums, expected $expected"
5625 }
5626 run_test 56q "check lfs find -gid and ! -gid"
5627
5628 test_56r() {
5629         local dir=$DIR/$tdir
5630
5631         setup_56 $dir $NUMFILES $NUMDIRS
5632
5633         local expected=12
5634         local cmd="$LFS find -size 0 -type f $dir"
5635         local nums=$($cmd | wc -l)
5636
5637         [ $nums -eq $expected ] ||
5638                 error "'$cmd' wrong: found $nums, expected $expected"
5639         expected=0
5640         cmd="$LFS find ! -size 0 -type f $dir"
5641         nums=$($cmd | wc -l)
5642         [ $nums -eq $expected ] ||
5643                 error "'$cmd' wrong: found $nums, expected $expected"
5644         echo "test" > $dir/$tfile
5645         echo "test2" > $dir/$tfile.2 && sync
5646         expected=1
5647         cmd="$LFS find -size 5 -type f $dir"
5648         nums=$($cmd | wc -l)
5649         [ $nums -eq $expected ] ||
5650                 error "'$cmd' wrong: found $nums, expected $expected"
5651         expected=1
5652         cmd="$LFS find -size +5 -type f $dir"
5653         nums=$($cmd | wc -l)
5654         [ $nums -eq $expected ] ||
5655                 error "'$cmd' wrong: found $nums, expected $expected"
5656         expected=2
5657         cmd="$LFS find -size +0 -type f $dir"
5658         nums=$($cmd | wc -l)
5659         [ $nums -eq $expected ] ||
5660                 error "'$cmd' wrong: found $nums, expected $expected"
5661         expected=2
5662         cmd="$LFS find ! -size -5 -type f $dir"
5663         nums=$($cmd | wc -l)
5664         [ $nums -eq $expected ] ||
5665                 error "'$cmd' wrong: found $nums, expected $expected"
5666         expected=12
5667         cmd="$LFS find -size -5 -type f $dir"
5668         nums=$($cmd | wc -l)
5669         [ $nums -eq $expected ] ||
5670                 error "'$cmd' wrong: found $nums, expected $expected"
5671 }
5672 run_test 56r "check lfs find -size works"
5673
5674 test_56s() { # LU-611 #LU-9369
5675         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5676
5677         local dir=$DIR/$tdir
5678         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5679
5680         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5681         for i in $(seq $NUMDIRS); do
5682                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5683         done
5684
5685         local expected=$NUMDIRS
5686         local cmd="$LFS find -c $OSTCOUNT $dir"
5687         local nums=$($cmd | wc -l)
5688
5689         [ $nums -eq $expected ] || {
5690                 $LFS getstripe -R $dir
5691                 error "'$cmd' wrong: found $nums, expected $expected"
5692         }
5693
5694         expected=$((NUMDIRS + onestripe))
5695         cmd="$LFS find -stripe-count +0 -type f $dir"
5696         nums=$($cmd | wc -l)
5697         [ $nums -eq $expected ] || {
5698                 $LFS getstripe -R $dir
5699                 error "'$cmd' wrong: found $nums, expected $expected"
5700         }
5701
5702         expected=$onestripe
5703         cmd="$LFS find -stripe-count 1 -type f $dir"
5704         nums=$($cmd | wc -l)
5705         [ $nums -eq $expected ] || {
5706                 $LFS getstripe -R $dir
5707                 error "'$cmd' wrong: found $nums, expected $expected"
5708         }
5709
5710         cmd="$LFS find -stripe-count -2 -type f $dir"
5711         nums=$($cmd | wc -l)
5712         [ $nums -eq $expected ] || {
5713                 $LFS getstripe -R $dir
5714                 error "'$cmd' wrong: found $nums, expected $expected"
5715         }
5716
5717         expected=0
5718         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5719         nums=$($cmd | wc -l)
5720         [ $nums -eq $expected ] || {
5721                 $LFS getstripe -R $dir
5722                 error "'$cmd' wrong: found $nums, expected $expected"
5723         }
5724 }
5725 run_test 56s "check lfs find -stripe-count works"
5726
5727 test_56t() { # LU-611 #LU-9369
5728         local dir=$DIR/$tdir
5729
5730         setup_56 $dir 0 $NUMDIRS
5731         for i in $(seq $NUMDIRS); do
5732                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5733         done
5734
5735         local expected=$NUMDIRS
5736         local cmd="$LFS find -S 8M $dir"
5737         local nums=$($cmd | wc -l)
5738
5739         [ $nums -eq $expected ] || {
5740                 $LFS getstripe -R $dir
5741                 error "'$cmd' wrong: found $nums, expected $expected"
5742         }
5743         rm -rf $dir
5744
5745         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5746
5747         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5748
5749         expected=$(((NUMDIRS + 1) * NUMFILES))
5750         cmd="$LFS find -stripe-size 512k -type f $dir"
5751         nums=$($cmd | wc -l)
5752         [ $nums -eq $expected ] ||
5753                 error "'$cmd' wrong: found $nums, expected $expected"
5754
5755         cmd="$LFS find -stripe-size +320k -type f $dir"
5756         nums=$($cmd | wc -l)
5757         [ $nums -eq $expected ] ||
5758                 error "'$cmd' wrong: found $nums, expected $expected"
5759
5760         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5761         cmd="$LFS find -stripe-size +200k -type f $dir"
5762         nums=$($cmd | wc -l)
5763         [ $nums -eq $expected ] ||
5764                 error "'$cmd' wrong: found $nums, expected $expected"
5765
5766         cmd="$LFS find -stripe-size -640k -type f $dir"
5767         nums=$($cmd | wc -l)
5768         [ $nums -eq $expected ] ||
5769                 error "'$cmd' wrong: found $nums, expected $expected"
5770
5771         expected=4
5772         cmd="$LFS find -stripe-size 256k -type f $dir"
5773         nums=$($cmd | wc -l)
5774         [ $nums -eq $expected ] ||
5775                 error "'$cmd' wrong: found $nums, expected $expected"
5776
5777         cmd="$LFS find -stripe-size -320k -type f $dir"
5778         nums=$($cmd | wc -l)
5779         [ $nums -eq $expected ] ||
5780                 error "'$cmd' wrong: found $nums, expected $expected"
5781
5782         expected=0
5783         cmd="$LFS find -stripe-size 1024k -type f $dir"
5784         nums=$($cmd | wc -l)
5785         [ $nums -eq $expected ] ||
5786                 error "'$cmd' wrong: found $nums, expected $expected"
5787 }
5788 run_test 56t "check lfs find -stripe-size works"
5789
5790 test_56u() { # LU-611
5791         local dir=$DIR/$tdir
5792
5793         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5794
5795         if [[ $OSTCOUNT -gt 1 ]]; then
5796                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5797                 onestripe=4
5798         else
5799                 onestripe=0
5800         fi
5801
5802         local expected=$(((NUMDIRS + 1) * NUMFILES))
5803         local cmd="$LFS find -stripe-index 0 -type f $dir"
5804         local nums=$($cmd | wc -l)
5805
5806         [ $nums -eq $expected ] ||
5807                 error "'$cmd' wrong: found $nums, expected $expected"
5808
5809         expected=$onestripe
5810         cmd="$LFS find -stripe-index 1 -type f $dir"
5811         nums=$($cmd | wc -l)
5812         [ $nums -eq $expected ] ||
5813                 error "'$cmd' wrong: found $nums, expected $expected"
5814
5815         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5816         nums=$($cmd | wc -l)
5817         [ $nums -eq $expected ] ||
5818                 error "'$cmd' wrong: found $nums, expected $expected"
5819
5820         expected=0
5821         # This should produce an error and not return any files
5822         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5823         nums=$($cmd 2>/dev/null | wc -l)
5824         [ $nums -eq $expected ] ||
5825                 error "'$cmd' wrong: found $nums, expected $expected"
5826
5827         if [[ $OSTCOUNT -gt 1 ]]; then
5828                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5829                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5830                 nums=$($cmd | wc -l)
5831                 [ $nums -eq $expected ] ||
5832                         error "'$cmd' wrong: found $nums, expected $expected"
5833         fi
5834 }
5835 run_test 56u "check lfs find -stripe-index works"
5836
5837 test_56v() {
5838         local mdt_idx=0
5839         local dir=$DIR/$tdir
5840
5841         setup_56 $dir $NUMFILES $NUMDIRS
5842
5843         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5844         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5845
5846         for file in $($LFS find -m $UUID $dir); do
5847                 file_midx=$($LFS getstripe -m $file)
5848                 [ $file_midx -eq $mdt_idx ] ||
5849                         error "lfs find -m $UUID != getstripe -m $file_midx"
5850         done
5851 }
5852 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5853
5854 test_56w() {
5855         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5857
5858         local dir=$DIR/$tdir
5859
5860         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5861
5862         local stripe_size=$($LFS getstripe -S -d $dir) ||
5863                 error "$LFS getstripe -S -d $dir failed"
5864         stripe_size=${stripe_size%% *}
5865
5866         local file_size=$((stripe_size * OSTCOUNT))
5867         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5868         local required_space=$((file_num * file_size))
5869         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5870                            head -n1)
5871         [[ $free_space -le $((required_space / 1024)) ]] &&
5872                 skip_env "need $required_space, have $free_space kbytes"
5873
5874         local dd_bs=65536
5875         local dd_count=$((file_size / dd_bs))
5876
5877         # write data into the files
5878         local i
5879         local j
5880         local file
5881
5882         for i in $(seq $NUMFILES); do
5883                 file=$dir/file$i
5884                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5885                         error "write data into $file failed"
5886         done
5887         for i in $(seq $NUMDIRS); do
5888                 for j in $(seq $NUMFILES); do
5889                         file=$dir/dir$i/file$j
5890                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5891                                 error "write data into $file failed"
5892                 done
5893         done
5894
5895         # $LFS_MIGRATE will fail if hard link migration is unsupported
5896         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5897                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5898                         error "creating links to $dir/dir1/file1 failed"
5899         fi
5900
5901         local expected=-1
5902
5903         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5904
5905         # lfs_migrate file
5906         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5907
5908         echo "$cmd"
5909         eval $cmd || error "$cmd failed"
5910
5911         check_stripe_count $dir/file1 $expected
5912
5913         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5914         then
5915                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5916                 # OST 1 if it is on OST 0. This file is small enough to
5917                 # be on only one stripe.
5918                 file=$dir/migr_1_ost
5919                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5920                         error "write data into $file failed"
5921                 local obdidx=$($LFS getstripe -i $file)
5922                 local oldmd5=$(md5sum $file)
5923                 local newobdidx=0
5924
5925                 [[ $obdidx -eq 0 ]] && newobdidx=1
5926                 cmd="$LFS migrate -i $newobdidx $file"
5927                 echo $cmd
5928                 eval $cmd || error "$cmd failed"
5929
5930                 local realobdix=$($LFS getstripe -i $file)
5931                 local newmd5=$(md5sum $file)
5932
5933                 [[ $newobdidx -ne $realobdix ]] &&
5934                         error "new OST is different (was=$obdidx, "\
5935                               "wanted=$newobdidx, got=$realobdix)"
5936                 [[ "$oldmd5" != "$newmd5" ]] &&
5937                         error "md5sum differ: $oldmd5, $newmd5"
5938         fi
5939
5940         # lfs_migrate dir
5941         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5942         echo "$cmd"
5943         eval $cmd || error "$cmd failed"
5944
5945         for j in $(seq $NUMFILES); do
5946                 check_stripe_count $dir/dir1/file$j $expected
5947         done
5948
5949         # lfs_migrate works with lfs find
5950         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5951              $LFS_MIGRATE -y -c $expected"
5952         echo "$cmd"
5953         eval $cmd || error "$cmd failed"
5954
5955         for i in $(seq 2 $NUMFILES); do
5956                 check_stripe_count $dir/file$i $expected
5957         done
5958         for i in $(seq 2 $NUMDIRS); do
5959                 for j in $(seq $NUMFILES); do
5960                 check_stripe_count $dir/dir$i/file$j $expected
5961                 done
5962         done
5963 }
5964 run_test 56w "check lfs_migrate -c stripe_count works"
5965
5966 test_56wb() {
5967         local file1=$DIR/$tdir/file1
5968         local create_pool=false
5969         local initial_pool=$($LFS getstripe -p $DIR)
5970         local pool_list=()
5971         local pool=""
5972
5973         echo -n "Creating test dir..."
5974         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5975         echo "done."
5976
5977         echo -n "Creating test file..."
5978         touch $file1 || error "cannot create file"
5979         echo "done."
5980
5981         echo -n "Detecting existing pools..."
5982         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
5983
5984         if [ ${#pool_list[@]} -gt 0 ]; then
5985                 echo "${pool_list[@]}"
5986                 for thispool in "${pool_list[@]}"; do
5987                         if [[ -z "$initial_pool" ||
5988                               "$initial_pool" != "$thispool" ]]; then
5989                                 pool="$thispool"
5990                                 echo "Using existing pool '$pool'"
5991                                 break
5992                         fi
5993                 done
5994         else
5995                 echo "none detected."
5996         fi
5997         if [ -z "$pool" ]; then
5998                 pool=${POOL:-testpool}
5999                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6000                 echo -n "Creating pool '$pool'..."
6001                 create_pool=true
6002                 pool_add $pool &> /dev/null ||
6003                         error "pool_add failed"
6004                 echo "done."
6005
6006                 echo -n "Adding target to pool..."
6007                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6008                         error "pool_add_targets failed"
6009                 echo "done."
6010         fi
6011
6012         echo -n "Setting pool using -p option..."
6013         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6014                 error "migrate failed rc = $?"
6015         echo "done."
6016
6017         echo -n "Verifying test file is in pool after migrating..."
6018         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6019                 error "file was not migrated to pool $pool"
6020         echo "done."
6021
6022         echo -n "Removing test file from pool '$pool'..."
6023         $LFS migrate $file1 &> /dev/null ||
6024                 error "cannot remove from pool"
6025         [ "$($LFS getstripe -p $file1)" ] &&
6026                 error "pool still set"
6027         echo "done."
6028
6029         echo -n "Setting pool using --pool option..."
6030         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6031                 error "migrate failed rc = $?"
6032         echo "done."
6033
6034         # Clean up
6035         rm -f $file1
6036         if $create_pool; then
6037                 destroy_test_pools 2> /dev/null ||
6038                         error "destroy test pools failed"
6039         fi
6040 }
6041 run_test 56wb "check lfs_migrate pool support"
6042
6043 test_56wc() {
6044         local file1="$DIR/$tdir/file1"
6045
6046         echo -n "Creating test dir..."
6047         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6048         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6049         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6050                 error "cannot set stripe"
6051         echo "done"
6052
6053         echo -n "Setting initial stripe for test file..."
6054         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6055                 error "cannot set stripe"
6056         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6057                 error "stripe size not set"
6058         echo "done."
6059
6060         # File currently set to -S 512K -c 1
6061
6062         # Ensure -c and -S options are rejected when -R is set
6063         echo -n "Verifying incompatible options are detected..."
6064         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6065                 error "incompatible -c and -R options not detected"
6066         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6067                 error "incompatible -S and -R options not detected"
6068         echo "done."
6069
6070         # Ensure unrecognized options are passed through to 'lfs migrate'
6071         echo -n "Verifying -S option is passed through to lfs migrate..."
6072         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6073                 error "migration failed"
6074         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6075                 error "file was not restriped"
6076         echo "done."
6077
6078         # File currently set to -S 1M -c 1
6079
6080         # Ensure long options are supported
6081         echo -n "Verifying long options supported..."
6082         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6083                 error "long option without argument not supported"
6084         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6085                 error "long option with argument not supported"
6086         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6087                 error "file not restriped with --stripe-size option"
6088         echo "done."
6089
6090         # File currently set to -S 512K -c 1
6091
6092         if [ "$OSTCOUNT" -gt 1 ]; then
6093                 echo -n "Verifying explicit stripe count can be set..."
6094                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6095                         error "migrate failed"
6096                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6097                         error "file not restriped to explicit count"
6098                 echo "done."
6099         fi
6100
6101         # File currently set to -S 512K -c 1 or -S 512K -c 2
6102
6103         # Ensure parent striping is used if -R is set, and no stripe
6104         # count or size is specified
6105         echo -n "Setting stripe for parent directory..."
6106         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6107                 error "cannot set stripe"
6108         echo "done."
6109
6110         echo -n "Verifying restripe option uses parent stripe settings..."
6111         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6112                 error "migrate failed"
6113         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6114                 error "file not restriped to parent settings"
6115         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6116                 error "file not restriped to parent settings"
6117         echo "done."
6118
6119         # File currently set to -S 1M -c 1
6120
6121         # Ensure striping is preserved if -R is not set, and no stripe
6122         # count or size is specified
6123         echo -n "Verifying striping size preserved when not specified..."
6124         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6125         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6126                 error "cannot set stripe on parent directory"
6127         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6128                 error "migrate failed"
6129         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6130                 error "file was restriped"
6131         echo "done."
6132
6133         # Ensure file name properly detected when final option has no argument
6134         echo -n "Verifying file name properly detected..."
6135         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6136                 error "file name interpreted as option argument"
6137         echo "done."
6138
6139         # Clean up
6140         rm -f "$file1"
6141 }
6142 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6143
6144 test_56wd() {
6145         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6146
6147         local file1=$DIR/$tdir/file1
6148
6149         echo -n "Creating test dir..."
6150         test_mkdir $DIR/$tdir || error "cannot create dir"
6151         echo "done."
6152
6153         echo -n "Creating test file..."
6154         touch $file1
6155         echo "done."
6156
6157         # Ensure 'lfs migrate' will fail by using a non-existent option,
6158         # and make sure rsync is not called to recover
6159         echo -n "Make sure --no-rsync option works..."
6160         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6161                 grep -q 'refusing to fall back to rsync' ||
6162                 error "rsync was called with --no-rsync set"
6163         echo "done."
6164
6165         # Ensure rsync is called without trying 'lfs migrate' first
6166         echo -n "Make sure --rsync option works..."
6167         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6168                 grep -q 'falling back to rsync' &&
6169                 error "lfs migrate was called with --rsync set"
6170         echo "done."
6171
6172         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6173         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6174                 grep -q 'at the same time' ||
6175                 error "--rsync and --no-rsync accepted concurrently"
6176         echo "done."
6177
6178         # Clean up
6179         rm -f $file1
6180 }
6181 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6182
6183 test_56x() {
6184         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6185         check_swap_layouts_support
6186
6187         local dir=$DIR/$tdir
6188         local ref1=/etc/passwd
6189         local file1=$dir/file1
6190
6191         test_mkdir $dir || error "creating dir $dir"
6192         $LFS setstripe -c 2 $file1
6193         cp $ref1 $file1
6194         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6195         stripe=$($LFS getstripe -c $file1)
6196         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6197         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6198
6199         # clean up
6200         rm -f $file1
6201 }
6202 run_test 56x "lfs migration support"
6203
6204 test_56xa() {
6205         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6206         check_swap_layouts_support
6207
6208         local dir=$DIR/$tdir/$testnum
6209
6210         test_mkdir -p $dir
6211
6212         local ref1=/etc/passwd
6213         local file1=$dir/file1
6214
6215         $LFS setstripe -c 2 $file1
6216         cp $ref1 $file1
6217         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6218
6219         local stripe=$($LFS getstripe -c $file1)
6220
6221         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6222         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6223
6224         # clean up
6225         rm -f $file1
6226 }
6227 run_test 56xa "lfs migration --block support"
6228
6229 check_migrate_links() {
6230         local dir="$1"
6231         local file1="$dir/file1"
6232         local begin="$2"
6233         local count="$3"
6234         local total_count=$(($begin + $count - 1))
6235         local symlink_count=10
6236         local uniq_count=10
6237
6238         if [ ! -f "$file1" ]; then
6239                 echo -n "creating initial file..."
6240                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6241                         error "cannot setstripe initial file"
6242                 echo "done"
6243
6244                 echo -n "creating symlinks..."
6245                 for s in $(seq 1 $symlink_count); do
6246                         ln -s "$file1" "$dir/slink$s" ||
6247                                 error "cannot create symlinks"
6248                 done
6249                 echo "done"
6250
6251                 echo -n "creating nonlinked files..."
6252                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6253                         error "cannot create nonlinked files"
6254                 echo "done"
6255         fi
6256
6257         # create hard links
6258         if [ ! -f "$dir/file$total_count" ]; then
6259                 echo -n "creating hard links $begin:$total_count..."
6260                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6261                         /dev/null || error "cannot create hard links"
6262                 echo "done"
6263         fi
6264
6265         echo -n "checking number of hard links listed in xattrs..."
6266         local fid=$($LFS getstripe -F "$file1")
6267         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6268
6269         echo "${#paths[*]}"
6270         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6271                         skip "hard link list has unexpected size, skipping test"
6272         fi
6273         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6274                         error "link names should exceed xattrs size"
6275         fi
6276
6277         echo -n "migrating files..."
6278         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
6279         local rc=$?
6280         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6281         echo "done"
6282
6283         # make sure all links have been properly migrated
6284         echo -n "verifying files..."
6285         fid=$($LFS getstripe -F "$file1") ||
6286                 error "cannot get fid for file $file1"
6287         for i in $(seq 2 $total_count); do
6288                 local fid2=$($LFS getstripe -F $dir/file$i)
6289
6290                 [ "$fid2" == "$fid" ] ||
6291                         error "migrated hard link has mismatched FID"
6292         done
6293
6294         # make sure hard links were properly detected, and migration was
6295         # performed only once for the entire link set; nonlinked files should
6296         # also be migrated
6297         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
6298         local expected=$(($uniq_count + 1))
6299
6300         [ "$actual" -eq  "$expected" ] ||
6301                 error "hard links individually migrated ($actual != $expected)"
6302
6303         # make sure the correct number of hard links are present
6304         local hardlinks=$(stat -c '%h' "$file1")
6305
6306         [ $hardlinks -eq $total_count ] ||
6307                 error "num hard links $hardlinks != $total_count"
6308         echo "done"
6309
6310         return 0
6311 }
6312
6313 test_56xb() {
6314         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6315                 skip "Need MDS version at least 2.10.55"
6316
6317         local dir="$DIR/$tdir"
6318
6319         test_mkdir "$dir" || error "cannot create dir $dir"
6320
6321         echo "testing lfs migrate mode when all links fit within xattrs"
6322         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6323
6324         echo "testing rsync mode when all links fit within xattrs"
6325         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6326
6327         echo "testing lfs migrate mode when all links do not fit within xattrs"
6328         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6329
6330         echo "testing rsync mode when all links do not fit within xattrs"
6331         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6332
6333
6334         # clean up
6335         rm -rf $dir
6336 }
6337 run_test 56xb "lfs migration hard link support"
6338
6339 test_56xc() {
6340         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6341
6342         local dir="$DIR/$tdir"
6343
6344         test_mkdir "$dir" || error "cannot create dir $dir"
6345
6346         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6347         echo -n "Setting initial stripe for 20MB test file..."
6348         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
6349         echo "done"
6350         echo -n "Sizing 20MB test file..."
6351         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6352         echo "done"
6353         echo -n "Verifying small file autostripe count is 1..."
6354         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
6355                 error "cannot migrate 20MB file"
6356         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6357                 error "cannot get stripe for $dir/20mb"
6358         [ $stripe_count -eq 1 ] ||
6359                 error "unexpected stripe count $stripe_count for 20MB file"
6360         rm -f "$dir/20mb"
6361         echo "done"
6362
6363         # Test 2: File is small enough to fit within the available space on
6364         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6365         # have at least an additional 1KB for each desired stripe for test 3
6366         echo -n "Setting stripe for 1GB test file..."
6367         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
6368         echo "done"
6369         echo -n "Sizing 1GB test file..."
6370         # File size is 1GB + 3KB
6371         truncate "$dir/1gb" 1073744896 &> /dev/null ||
6372                 error "cannot create 1GB test file"
6373         echo "done"
6374         echo -n "Migrating 1GB file..."
6375         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
6376                 error "cannot migrate file"
6377         echo "done"
6378         echo -n "Verifying autostripe count is sqrt(n) + 1..."
6379         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6380                 error "cannot get stripe for $dir/1gb"
6381         [ $stripe_count -eq 2 ] ||
6382                 error "unexpected stripe count $stripe_count (expected 2)"
6383         echo "done"
6384
6385         # Test 3: File is too large to fit within the available space on
6386         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6387         if [ $OSTCOUNT -ge 3 ]; then
6388                 # The required available space is calculated as
6389                 # file size (1GB + 3KB) / OST count (3).
6390                 local kb_per_ost=349526
6391
6392                 echo -n "Migrating 1GB file..."
6393                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
6394                         /dev/null || error "cannot migrate file"
6395                 echo "done"
6396
6397                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6398                 echo -n "Verifying autostripe count with limited space..."
6399                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
6400                         error "unexpected stripe count $stripe_count (wanted 3)"
6401                 echo "done"
6402         fi
6403
6404         # clean up
6405         rm -rf $dir
6406 }
6407 run_test 56xc "lfs migration autostripe"
6408
6409 test_56y() {
6410         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6411                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6412
6413         local res=""
6414         local dir=$DIR/$tdir
6415         local f1=$dir/file1
6416         local f2=$dir/file2
6417
6418         test_mkdir -p $dir || error "creating dir $dir"
6419         touch $f1 || error "creating std file $f1"
6420         $MULTIOP $f2 H2c || error "creating released file $f2"
6421
6422         # a directory can be raid0, so ask only for files
6423         res=$($LFS find $dir -L raid0 -type f | wc -l)
6424         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6425
6426         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6427         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6428
6429         # only files can be released, so no need to force file search
6430         res=$($LFS find $dir -L released)
6431         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6432
6433         res=$($LFS find $dir -type f \! -L released)
6434         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6435 }
6436 run_test 56y "lfs find -L raid0|released"
6437
6438 test_56z() { # LU-4824
6439         # This checks to make sure 'lfs find' continues after errors
6440         # There are two classes of errors that should be caught:
6441         # - If multiple paths are provided, all should be searched even if one
6442         #   errors out
6443         # - If errors are encountered during the search, it should not terminate
6444         #   early
6445         local dir=$DIR/$tdir
6446         local i
6447
6448         test_mkdir $dir
6449         for i in d{0..9}; do
6450                 test_mkdir $dir/$i
6451         done
6452         touch $dir/d{0..9}/$tfile
6453         $LFS find $DIR/non_existent_dir $dir &&
6454                 error "$LFS find did not return an error"
6455         # Make a directory unsearchable. This should NOT be the last entry in
6456         # directory order.  Arbitrarily pick the 6th entry
6457         chmod 700 $($LFS find $dir -type d | sed '6!d')
6458
6459         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6460
6461         # The user should be able to see 10 directories and 9 files
6462         [ $count == 19 ] || error "$LFS find did not continue after error"
6463 }
6464 run_test 56z "lfs find should continue after an error"
6465
6466 test_56aa() { # LU-5937
6467         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6468
6469         local dir=$DIR/$tdir
6470
6471         mkdir $dir
6472         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6473
6474         createmany -o $dir/striped_dir/${tfile}- 1024
6475         local dirs=$($LFS find --size +8k $dir/)
6476
6477         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6478 }
6479 run_test 56aa "lfs find --size under striped dir"
6480
6481 test_56ab() { # LU-10705
6482         test_mkdir $DIR/$tdir
6483         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6484         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6485         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6486         # Flush writes to ensure valid blocks.  Need to be more thorough for
6487         # ZFS, since blocks are not allocated/returned to client immediately.
6488         sync_all_data
6489         wait_zfs_commit ost1 2
6490         cancel_lru_locks osc
6491         ls -ls $DIR/$tdir
6492
6493         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6494
6495         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6496
6497         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6498         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6499
6500         rm -f $DIR/$tdir/$tfile.[123]
6501 }
6502 run_test 56ab "lfs find --blocks"
6503
6504 test_56ba() {
6505         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6506                 skip "Need MDS version at least 2.10.50"
6507
6508         # Create composite files with one component
6509         local dir=$DIR/$tdir
6510
6511         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6512         # Create composite files with three components
6513         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6514         # Create non-composite files
6515         createmany -o $dir/${tfile}- 10
6516
6517         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6518
6519         [[ $nfiles == 10 ]] ||
6520                 error "lfs find -E 1M found $nfiles != 10 files"
6521
6522         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6523         [[ $nfiles == 25 ]] ||
6524                 error "lfs find ! -E 1M found $nfiles != 25 files"
6525
6526         # All files have a component that starts at 0
6527         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6528         [[ $nfiles == 35 ]] ||
6529                 error "lfs find --component-start 0 - $nfiles != 35 files"
6530
6531         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6532         [[ $nfiles == 15 ]] ||
6533                 error "lfs find --component-start 2M - $nfiles != 15 files"
6534
6535         # All files created here have a componenet that does not starts at 2M
6536         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6537         [[ $nfiles == 35 ]] ||
6538                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6539
6540         # Find files with a specified number of components
6541         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6542         [[ $nfiles == 15 ]] ||
6543                 error "lfs find --component-count 3 - $nfiles != 15 files"
6544
6545         # Remember non-composite files have a component count of zero
6546         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6547         [[ $nfiles == 10 ]] ||
6548                 error "lfs find --component-count 0 - $nfiles != 10 files"
6549
6550         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6551         [[ $nfiles == 20 ]] ||
6552                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6553
6554         # All files have a flag called "init"
6555         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6556         [[ $nfiles == 35 ]] ||
6557                 error "lfs find --component-flags init - $nfiles != 35 files"
6558
6559         # Multi-component files will have a component not initialized
6560         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6561         [[ $nfiles == 15 ]] ||
6562                 error "lfs find !--component-flags init - $nfiles != 15 files"
6563
6564         rm -rf $dir
6565
6566 }
6567 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6568
6569 test_56ca() {
6570         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6571                 skip "Need MDS version at least 2.10.57"
6572
6573         local td=$DIR/$tdir
6574         local tf=$td/$tfile
6575         local dir
6576         local nfiles
6577         local cmd
6578         local i
6579         local j
6580
6581         # create mirrored directories and mirrored files
6582         mkdir $td || error "mkdir $td failed"
6583         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6584         createmany -o $tf- 10 || error "create $tf- failed"
6585
6586         for i in $(seq 2); do
6587                 dir=$td/dir$i
6588                 mkdir $dir || error "mkdir $dir failed"
6589                 $LFS mirror create -N$((3 + i)) $dir ||
6590                         error "create mirrored dir $dir failed"
6591                 createmany -o $dir/$tfile- 10 ||
6592                         error "create $dir/$tfile- failed"
6593         done
6594
6595         # change the states of some mirrored files
6596         echo foo > $tf-6
6597         for i in $(seq 2); do
6598                 dir=$td/dir$i
6599                 for j in $(seq 4 9); do
6600                         echo foo > $dir/$tfile-$j
6601                 done
6602         done
6603
6604         # find mirrored files with specific mirror count
6605         cmd="$LFS find --mirror-count 3 --type f $td"
6606         nfiles=$($cmd | wc -l)
6607         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6608
6609         cmd="$LFS find ! --mirror-count 3 --type f $td"
6610         nfiles=$($cmd | wc -l)
6611         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6612
6613         cmd="$LFS find --mirror-count +2 --type f $td"
6614         nfiles=$($cmd | wc -l)
6615         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6616
6617         cmd="$LFS find --mirror-count -6 --type f $td"
6618         nfiles=$($cmd | wc -l)
6619         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6620
6621         # find mirrored files with specific file state
6622         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6623         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6624
6625         cmd="$LFS find --mirror-state=ro --type f $td"
6626         nfiles=$($cmd | wc -l)
6627         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6628
6629         cmd="$LFS find ! --mirror-state=ro --type f $td"
6630         nfiles=$($cmd | wc -l)
6631         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6632
6633         cmd="$LFS find --mirror-state=wp --type f $td"
6634         nfiles=$($cmd | wc -l)
6635         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6636
6637         cmd="$LFS find ! --mirror-state=sp --type f $td"
6638         nfiles=$($cmd | wc -l)
6639         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6640 }
6641 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6642
6643 test_57a() {
6644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6645         # note test will not do anything if MDS is not local
6646         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6647                 skip_env "ldiskfs only test"
6648         fi
6649         remote_mds_nodsh && skip "remote MDS with nodsh"
6650
6651         local MNTDEV="osd*.*MDT*.mntdev"
6652         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6653         [ -z "$DEV" ] && error "can't access $MNTDEV"
6654         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6655                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6656                         error "can't access $DEV"
6657                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6658                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6659                 rm $TMP/t57a.dump
6660         done
6661 }
6662 run_test 57a "verify MDS filesystem created with large inodes =="
6663
6664 test_57b() {
6665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6666         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6667                 skip_env "ldiskfs only test"
6668         fi
6669         remote_mds_nodsh && skip "remote MDS with nodsh"
6670
6671         local dir=$DIR/$tdir
6672         local filecount=100
6673         local file1=$dir/f1
6674         local fileN=$dir/f$filecount
6675
6676         rm -rf $dir || error "removing $dir"
6677         test_mkdir -c1 $dir
6678         local mdtidx=$($LFS getstripe -m $dir)
6679         local mdtname=MDT$(printf %04x $mdtidx)
6680         local facet=mds$((mdtidx + 1))
6681
6682         echo "mcreating $filecount files"
6683         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6684
6685         # verify that files do not have EAs yet
6686         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6687                 error "$file1 has an EA"
6688         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6689                 error "$fileN has an EA"
6690
6691         sync
6692         sleep 1
6693         df $dir  #make sure we get new statfs data
6694         local mdsfree=$(do_facet $facet \
6695                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6696         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6697         local file
6698
6699         echo "opening files to create objects/EAs"
6700         for file in $(seq -f $dir/f%g 1 $filecount); do
6701                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6702                         error "opening $file"
6703         done
6704
6705         # verify that files have EAs now
6706         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6707         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6708
6709         sleep 1  #make sure we get new statfs data
6710         df $dir
6711         local mdsfree2=$(do_facet $facet \
6712                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6713         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6714
6715         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6716                 if [ "$mdsfree" != "$mdsfree2" ]; then
6717                         error "MDC before $mdcfree != after $mdcfree2"
6718                 else
6719                         echo "MDC before $mdcfree != after $mdcfree2"
6720                         echo "unable to confirm if MDS has large inodes"
6721                 fi
6722         fi
6723         rm -rf $dir
6724 }
6725 run_test 57b "default LOV EAs are stored inside large inodes ==="
6726
6727 test_58() {
6728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6729         [ -z "$(which wiretest 2>/dev/null)" ] &&
6730                         skip_env "could not find wiretest"
6731
6732         wiretest
6733 }
6734 run_test 58 "verify cross-platform wire constants =============="
6735
6736 test_59() {
6737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6738
6739         echo "touch 130 files"
6740         createmany -o $DIR/f59- 130
6741         echo "rm 130 files"
6742         unlinkmany $DIR/f59- 130
6743         sync
6744         # wait for commitment of removal
6745         wait_delete_completed
6746 }
6747 run_test 59 "verify cancellation of llog records async ========="
6748
6749 TEST60_HEAD="test_60 run $RANDOM"
6750 test_60a() {
6751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6752         remote_mgs_nodsh && skip "remote MGS with nodsh"
6753         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6754                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6755                         skip_env "missing subtest run-llog.sh"
6756
6757         log "$TEST60_HEAD - from kernel mode"
6758         do_facet mgs "$LCTL dk > /dev/null"
6759         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6760         do_facet mgs $LCTL dk > $TMP/$tfile
6761
6762         # LU-6388: test llog_reader
6763         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6764         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6765         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6766                         skip_env "missing llog_reader"
6767         local fstype=$(facet_fstype mgs)
6768         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6769                 skip_env "Only for ldiskfs or zfs type mgs"
6770
6771         local mntpt=$(facet_mntpt mgs)
6772         local mgsdev=$(mgsdevname 1)
6773         local fid_list
6774         local fid
6775         local rec_list
6776         local rec
6777         local rec_type
6778         local obj_file
6779         local path
6780         local seq
6781         local oid
6782         local pass=true
6783
6784         #get fid and record list
6785         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6786                 tail -n 4))
6787         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6788                 tail -n 4))
6789         #remount mgs as ldiskfs or zfs type
6790         stop mgs || error "stop mgs failed"
6791         mount_fstype mgs || error "remount mgs failed"
6792         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6793                 fid=${fid_list[i]}
6794                 rec=${rec_list[i]}
6795                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6796                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6797                 oid=$((16#$oid))
6798
6799                 case $fstype in
6800                         ldiskfs )
6801                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6802                         zfs )
6803                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6804                 esac
6805                 echo "obj_file is $obj_file"
6806                 do_facet mgs $llog_reader $obj_file
6807
6808                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6809                         awk '{ print $3 }' | sed -e "s/^type=//g")
6810                 if [ $rec_type != $rec ]; then
6811                         echo "FAILED test_60a wrong record type $rec_type," \
6812                               "should be $rec"
6813                         pass=false
6814                         break
6815                 fi
6816
6817                 #check obj path if record type is LLOG_LOGID_MAGIC
6818                 if [ "$rec" == "1064553b" ]; then
6819                         path=$(do_facet mgs $llog_reader $obj_file |
6820                                 grep "path=" | awk '{ print $NF }' |
6821                                 sed -e "s/^path=//g")
6822                         if [ $obj_file != $mntpt/$path ]; then
6823                                 echo "FAILED test_60a wrong obj path" \
6824                                       "$montpt/$path, should be $obj_file"
6825                                 pass=false
6826                                 break
6827                         fi
6828                 fi
6829         done
6830         rm -f $TMP/$tfile
6831         #restart mgs before "error", otherwise it will block the next test
6832         stop mgs || error "stop mgs failed"
6833         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6834         $pass || error "test failed, see FAILED test_60a messages for specifics"
6835 }
6836 run_test 60a "llog_test run from kernel module and test llog_reader"
6837
6838 test_60b() { # bug 6411
6839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6840
6841         dmesg > $DIR/$tfile
6842         LLOG_COUNT=$(do_facet mgs dmesg |
6843                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6844                           /llog_[a-z]*.c:[0-9]/ {
6845                                 if (marker)
6846                                         from_marker++
6847                                 from_begin++
6848                           }
6849                           END {
6850                                 if (marker)
6851                                         print from_marker
6852                                 else
6853                                         print from_begin
6854                           }")
6855
6856         [[ $LLOG_COUNT -gt 120 ]] &&
6857                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6858 }
6859 run_test 60b "limit repeated messages from CERROR/CWARN"
6860
6861 test_60c() {
6862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6863
6864         echo "create 5000 files"
6865         createmany -o $DIR/f60c- 5000
6866 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6867         lctl set_param fail_loc=0x80000137
6868         unlinkmany $DIR/f60c- 5000
6869         lctl set_param fail_loc=0
6870 }
6871 run_test 60c "unlink file when mds full"
6872
6873 test_60d() {
6874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6875
6876         SAVEPRINTK=$(lctl get_param -n printk)
6877         # verify "lctl mark" is even working"
6878         MESSAGE="test message ID $RANDOM $$"
6879         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6880         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6881
6882         lctl set_param printk=0 || error "set lnet.printk failed"
6883         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6884         MESSAGE="new test message ID $RANDOM $$"
6885         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6886         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6887         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6888
6889         lctl set_param -n printk="$SAVEPRINTK"
6890 }
6891 run_test 60d "test printk console message masking"
6892
6893 test_60e() {
6894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6895         remote_mds_nodsh && skip "remote MDS with nodsh"
6896
6897         touch $DIR/$tfile
6898 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6899         do_facet mds1 lctl set_param fail_loc=0x15b
6900         rm $DIR/$tfile
6901 }
6902 run_test 60e "no space while new llog is being created"
6903
6904 test_60g() {
6905         local pid
6906
6907         test_mkdir -c $MDSCOUNT $DIR/$tdir
6908         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6909
6910         (
6911                 local index=0
6912                 while true; do
6913                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6914                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6915                         index=$((index + 1))
6916                 done
6917         ) &
6918
6919         pid=$!
6920
6921         for i in $(seq 100); do 
6922                 # define OBD_FAIL_OSD_TXN_START    0x19a
6923                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6924                 usleep 100
6925         done
6926
6927         kill -9 $pid
6928
6929         mkdir $DIR/$tdir/new || error "mkdir failed"
6930         rmdir $DIR/$tdir/new || error "rmdir failed"
6931 }
6932 run_test 60g "transaction abort won't cause MDT hung"
6933
6934 test_60h() {
6935         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
6936                 skip "Need MDS version at least 2.12.52"
6937         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
6938
6939         local f
6940
6941         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
6942         #define OBD_FAIL_MDS_STRIPE_FID          0x189
6943         for fail_loc in 0x80000188 0x80000189; do
6944                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
6945                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
6946                         error "mkdir $dir-$fail_loc failed"
6947                 for i in {0..10}; do
6948                         # create may fail on missing stripe
6949                         echo $i > $DIR/$tdir-$fail_loc/$i
6950                 done
6951                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6952                         error "getdirstripe $tdir-$fail_loc failed"
6953                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
6954                         error "migrate $tdir-$fail_loc failed"
6955                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6956                         error "getdirstripe $tdir-$fail_loc failed"
6957                 pushd $DIR/$tdir-$fail_loc
6958                 for f in *; do
6959                         echo $f | cmp $f - || error "$f data mismatch"
6960                 done
6961                 popd
6962                 rm -rf $DIR/$tdir-$fail_loc
6963         done
6964 }
6965 run_test 60h "striped directory with missing stripes can be accessed"
6966
6967 test_61a() {
6968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6969
6970         f="$DIR/f61"
6971         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6972         cancel_lru_locks osc
6973         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6974         sync
6975 }
6976 run_test 61a "mmap() writes don't make sync hang ================"
6977
6978 test_61b() {
6979         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
6980 }
6981 run_test 61b "mmap() of unstriped file is successful"
6982
6983 # bug 2330 - insufficient obd_match error checking causes LBUG
6984 test_62() {
6985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6986
6987         f="$DIR/f62"
6988         echo foo > $f
6989         cancel_lru_locks osc
6990         lctl set_param fail_loc=0x405
6991         cat $f && error "cat succeeded, expect -EIO"
6992         lctl set_param fail_loc=0
6993 }
6994 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
6995 # match every page all of the time.
6996 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
6997
6998 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
6999 # Though this test is irrelevant anymore, it helped to reveal some
7000 # other grant bugs (LU-4482), let's keep it.
7001 test_63a() {   # was test_63
7002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7003
7004         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7005
7006         for i in `seq 10` ; do
7007                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7008                 sleep 5
7009                 kill $!
7010                 sleep 1
7011         done
7012
7013         rm -f $DIR/f63 || true
7014 }
7015 run_test 63a "Verify oig_wait interruption does not crash ======="
7016
7017 # bug 2248 - async write errors didn't return to application on sync
7018 # bug 3677 - async write errors left page locked
7019 test_63b() {
7020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7021
7022         debugsave
7023         lctl set_param debug=-1
7024
7025         # ensure we have a grant to do async writes
7026         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7027         rm $DIR/$tfile
7028
7029         sync    # sync lest earlier test intercept the fail_loc
7030
7031         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7032         lctl set_param fail_loc=0x80000406
7033         $MULTIOP $DIR/$tfile Owy && \
7034                 error "sync didn't return ENOMEM"
7035         sync; sleep 2; sync     # do a real sync this time to flush page
7036         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7037                 error "locked page left in cache after async error" || true
7038         debugrestore
7039 }
7040 run_test 63b "async write errors should be returned to fsync ==="
7041
7042 test_64a () {
7043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7044
7045         df $DIR
7046         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7047 }
7048 run_test 64a "verify filter grant calculations (in kernel) ====="
7049
7050 test_64b () {
7051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7052
7053         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7054 }
7055 run_test 64b "check out-of-space detection on client"
7056
7057 test_64c() {
7058         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7059 }
7060 run_test 64c "verify grant shrink"
7061
7062 # this does exactly what osc_request.c:osc_announce_cached() does in
7063 # order to calculate max amount of grants to ask from server
7064 want_grant() {
7065         local tgt=$1
7066
7067         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7068         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7069
7070         ((rpc_in_flight ++));
7071         nrpages=$((nrpages * rpc_in_flight))
7072
7073         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7074
7075         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7076
7077         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7078         local undirty=$((nrpages * PAGE_SIZE))
7079
7080         local max_extent_pages
7081         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7082             grep grant_max_extent_size | awk '{print $2}')
7083         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7084         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7085         local grant_extent_tax
7086         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7087             grep grant_extent_tax | awk '{print $2}')
7088
7089         undirty=$((undirty + nrextents * grant_extent_tax))
7090
7091         echo $undirty
7092 }
7093
7094 # this is size of unit for grant allocation. It should be equal to
7095 # what tgt_grant.c:tgt_grant_chunk() calculates
7096 grant_chunk() {
7097         local tgt=$1
7098         local max_brw_size
7099         local grant_extent_tax
7100
7101         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7102             grep max_brw_size | awk '{print $2}')
7103
7104         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7105             grep grant_extent_tax | awk '{print $2}')
7106
7107         echo $(((max_brw_size + grant_extent_tax) * 2))
7108 }
7109
7110 test_64d() {
7111         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7112                 skip "OST < 2.10.55 doesn't limit grants enough"
7113
7114         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7115         local file=$DIR/$tfile
7116
7117         [[ $($LCTL get_param osc.${tgt}.import |
7118              grep "connect_flags:.*grant_param") ]] ||
7119                 skip "no grant_param connect flag"
7120
7121         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7122
7123         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7124
7125         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7126         stack_trap "rm -f $file" EXIT
7127
7128         $LFS setstripe $file -i 0 -c 1
7129         dd if=/dev/zero of=$file bs=1M count=1000 &
7130         ddpid=$!
7131
7132         while true
7133         do
7134                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7135                 if [[ $cur_grant -gt $max_cur_granted ]]
7136                 then
7137                         kill $ddpid
7138                         error "cur_grant $cur_grant > $max_cur_granted"
7139                 fi
7140                 kill -0 $ddpid
7141                 [[ $? -ne 0 ]] && break;
7142                 sleep 2
7143         done
7144
7145         rm -f $DIR/$tfile
7146         wait_delete_completed
7147         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7148 }
7149 run_test 64d "check grant limit exceed"
7150
7151 # bug 1414 - set/get directories' stripe info
7152 test_65a() {
7153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7154
7155         test_mkdir $DIR/$tdir
7156         touch $DIR/$tdir/f1
7157         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7158 }
7159 run_test 65a "directory with no stripe info"
7160
7161 test_65b() {
7162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7163
7164         test_mkdir $DIR/$tdir
7165         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7166
7167         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7168                                                 error "setstripe"
7169         touch $DIR/$tdir/f2
7170         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7171 }
7172 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7173
7174 test_65c() {
7175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7176         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7177
7178         test_mkdir $DIR/$tdir
7179         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7180
7181         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7182                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7183         touch $DIR/$tdir/f3
7184         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7185 }
7186 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7187
7188 test_65d() {
7189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7190
7191         test_mkdir $DIR/$tdir
7192         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7193         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7194
7195         if [[ $STRIPECOUNT -le 0 ]]; then
7196                 sc=1
7197         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7198                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7199                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7200         else
7201                 sc=$(($STRIPECOUNT - 1))
7202         fi
7203         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7204         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7205         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7206                 error "lverify failed"
7207 }
7208 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7209
7210 test_65e() {
7211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7212
7213         test_mkdir $DIR/$tdir
7214
7215         $LFS setstripe $DIR/$tdir || error "setstripe"
7216         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7217                                         error "no stripe info failed"
7218         touch $DIR/$tdir/f6
7219         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7220 }
7221 run_test 65e "directory setstripe defaults"
7222
7223 test_65f() {
7224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7225
7226         test_mkdir $DIR/${tdir}f
7227         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7228                 error "setstripe succeeded" || true
7229 }
7230 run_test 65f "dir setstripe permission (should return error) ==="
7231
7232 test_65g() {
7233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7234
7235         test_mkdir $DIR/$tdir
7236         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7237
7238         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7239                 error "setstripe -S failed"
7240         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7241         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7242                 error "delete default stripe failed"
7243 }
7244 run_test 65g "directory setstripe -d"
7245
7246 test_65h() {
7247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7248
7249         test_mkdir $DIR/$tdir
7250         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7251
7252         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7253                 error "setstripe -S failed"
7254         test_mkdir $DIR/$tdir/dd1
7255         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7256                 error "stripe info inherit failed"
7257 }
7258 run_test 65h "directory stripe info inherit ===================="
7259
7260 test_65i() {
7261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7262
7263         save_layout_restore_at_exit $MOUNT
7264
7265         # bug6367: set non-default striping on root directory
7266         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7267
7268         # bug12836: getstripe on -1 default directory striping
7269         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7270
7271         # bug12836: getstripe -v on -1 default directory striping
7272         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7273
7274         # bug12836: new find on -1 default directory striping
7275         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7276 }
7277 run_test 65i "various tests to set root directory striping"
7278
7279 test_65j() { # bug6367
7280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7281
7282         sync; sleep 1
7283
7284         # if we aren't already remounting for each test, do so for this test
7285         if [ "$I_MOUNTED" = "yes" ]; then
7286                 cleanup || error "failed to unmount"
7287                 setup
7288         fi
7289
7290         save_layout_restore_at_exit $MOUNT
7291
7292         $LFS setstripe -d $MOUNT || error "setstripe failed"
7293 }
7294 run_test 65j "set default striping on root directory (bug 6367)="
7295
7296 cleanup_65k() {
7297         rm -rf $DIR/$tdir
7298         wait_delete_completed
7299         do_facet $SINGLEMDS "lctl set_param -n \
7300                 osp.$ost*MDT0000.max_create_count=$max_count"
7301         do_facet $SINGLEMDS "lctl set_param -n \
7302                 osp.$ost*MDT0000.create_count=$count"
7303         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7304         echo $INACTIVE_OSC "is Activate"
7305
7306         wait_osc_import_state mds ost$ostnum FULL
7307 }
7308
7309 test_65k() { # bug11679
7310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7311         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7312         remote_mds_nodsh && skip "remote MDS with nodsh"
7313
7314         local disable_precreate=true
7315         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7316                 disable_precreate=false
7317
7318         echo "Check OST status: "
7319         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7320                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7321
7322         for OSC in $MDS_OSCS; do
7323                 echo $OSC "is active"
7324                 do_facet $SINGLEMDS lctl --device %$OSC activate
7325         done
7326
7327         for INACTIVE_OSC in $MDS_OSCS; do
7328                 local ost=$(osc_to_ost $INACTIVE_OSC)
7329                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7330                                lov.*md*.target_obd |
7331                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7332
7333                 mkdir -p $DIR/$tdir
7334                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7335                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7336
7337                 echo "Deactivate: " $INACTIVE_OSC
7338                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7339
7340                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7341                               osp.$ost*MDT0000.create_count")
7342                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7343                                   osp.$ost*MDT0000.max_create_count")
7344                 $disable_precreate &&
7345                         do_facet $SINGLEMDS "lctl set_param -n \
7346                                 osp.$ost*MDT0000.max_create_count=0"
7347
7348                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7349                         [ -f $DIR/$tdir/$idx ] && continue
7350                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7351                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7352                                 { cleanup_65k;
7353                                   error "setstripe $idx should succeed"; }
7354                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7355                 done
7356                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7357                 rmdir $DIR/$tdir
7358
7359                 do_facet $SINGLEMDS "lctl set_param -n \
7360                         osp.$ost*MDT0000.max_create_count=$max_count"
7361                 do_facet $SINGLEMDS "lctl set_param -n \
7362                         osp.$ost*MDT0000.create_count=$count"
7363                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7364                 echo $INACTIVE_OSC "is Activate"
7365
7366                 wait_osc_import_state mds ost$ostnum FULL
7367         done
7368 }
7369 run_test 65k "validate manual striping works properly with deactivated OSCs"
7370
7371 test_65l() { # bug 12836
7372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7373
7374         test_mkdir -p $DIR/$tdir/test_dir
7375         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7376         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7377 }
7378 run_test 65l "lfs find on -1 stripe dir ========================"
7379
7380 test_65m() {
7381         local layout=$(save_layout $MOUNT)
7382         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7383                 restore_layout $MOUNT $layout
7384                 error "setstripe should fail by non-root users"
7385         }
7386         true
7387 }
7388 run_test 65m "normal user can't set filesystem default stripe"
7389
7390 test_65n() {
7391         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7392         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7393                 skip "Need MDS version at least 2.12.50"
7394         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7395
7396         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7397         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7398         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7399
7400         local root_layout=$(save_layout $MOUNT)
7401         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7402
7403         # new subdirectory under root directory should not inherit
7404         # the default layout from root
7405         local dir1=$MOUNT/$tdir-1
7406         mkdir $dir1 || error "mkdir $dir1 failed"
7407         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7408                 error "$dir1 shouldn't have LOV EA"
7409
7410         # delete the default layout on root directory
7411         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7412
7413         local dir2=$MOUNT/$tdir-2
7414         mkdir $dir2 || error "mkdir $dir2 failed"
7415         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7416                 error "$dir2 shouldn't have LOV EA"
7417
7418         # set a new striping pattern on root directory
7419         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7420         local new_def_stripe_size=$((def_stripe_size * 2))
7421         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7422                 error "set stripe size on $MOUNT failed"
7423
7424         # new file created in $dir2 should inherit the new stripe size from
7425         # the filesystem default
7426         local file2=$dir2/$tfile-2
7427         touch $file2 || error "touch $file2 failed"
7428
7429         local file2_stripe_size=$($LFS getstripe -S $file2)
7430         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7431                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7432
7433         local dir3=$MOUNT/$tdir-3
7434         mkdir $dir3 || error "mkdir $dir3 failed"
7435         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7436                 error "$dir3 shouldn't have LOV EA"
7437
7438         # set OST pool on root directory
7439         local pool=$TESTNAME
7440         pool_add $pool || error "add $pool failed"
7441         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7442                 error "add targets to $pool failed"
7443
7444         $LFS setstripe -p $pool $MOUNT ||
7445                 error "set OST pool on $MOUNT failed"
7446
7447         # new file created in $dir3 should inherit the pool from
7448         # the filesystem default
7449         local file3=$dir3/$tfile-3
7450         touch $file3 || error "touch $file3 failed"
7451
7452         local file3_pool=$($LFS getstripe -p $file3)
7453         [[ "$file3_pool" = "$pool" ]] ||
7454                 error "$file3 didn't inherit OST pool $pool"
7455
7456         local dir4=$MOUNT/$tdir-4
7457         mkdir $dir4 || error "mkdir $dir4 failed"
7458         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7459                 error "$dir4 shouldn't have LOV EA"
7460
7461         # new file created in $dir4 should inherit the pool from
7462         # the filesystem default
7463         local file4=$dir4/$tfile-4
7464         touch $file4 || error "touch $file4 failed"
7465
7466         local file4_pool=$($LFS getstripe -p $file4)
7467         [[ "$file4_pool" = "$pool" ]] ||
7468                 error "$file4 didn't inherit OST pool $pool"
7469
7470         # new subdirectory under non-root directory should inherit
7471         # the default layout from its parent directory
7472         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7473                 error "set directory layout on $dir4 failed"
7474
7475         local dir5=$dir4/$tdir-5
7476         mkdir $dir5 || error "mkdir $dir5 failed"
7477
7478         local dir4_layout=$(get_layout_param $dir4)
7479         local dir5_layout=$(get_layout_param $dir5)
7480         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7481                 error "$dir5 should inherit the default layout from $dir4"
7482 }
7483 run_test 65n "don't inherit default layout from root for new subdirectories"
7484
7485 # bug 2543 - update blocks count on client
7486 test_66() {
7487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7488
7489         COUNT=${COUNT:-8}
7490         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7491         sync; sync_all_data; sync; sync_all_data
7492         cancel_lru_locks osc
7493         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7494         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7495 }
7496 run_test 66 "update inode blocks count on client ==============="
7497
7498 meminfo() {
7499         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7500 }
7501
7502 swap_used() {
7503         swapon -s | awk '($1 == "'$1'") { print $4 }'
7504 }
7505
7506 # bug5265, obdfilter oa2dentry return -ENOENT
7507 # #define OBD_FAIL_SRV_ENOENT 0x217
7508 test_69() {
7509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7510         remote_ost_nodsh && skip "remote OST with nodsh"
7511
7512         f="$DIR/$tfile"
7513         $LFS setstripe -c 1 -i 0 $f
7514
7515         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7516
7517         do_facet ost1 lctl set_param fail_loc=0x217
7518         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7519         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7520
7521         do_facet ost1 lctl set_param fail_loc=0
7522         $DIRECTIO write $f 0 2 || error "write error"
7523
7524         cancel_lru_locks osc
7525         $DIRECTIO read $f 0 1 || error "read error"
7526
7527         do_facet ost1 lctl set_param fail_loc=0x217
7528         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7529
7530         do_facet ost1 lctl set_param fail_loc=0
7531         rm -f $f
7532 }
7533 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7534
7535 test_71() {
7536         test_mkdir $DIR/$tdir
7537         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7538         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7539 }
7540 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7541
7542 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7544         [ "$RUNAS_ID" = "$UID" ] &&
7545                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7546         # Check that testing environment is properly set up. Skip if not
7547         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7548                 skip_env "User $RUNAS_ID does not exist - skipping"
7549
7550         touch $DIR/$tfile
7551         chmod 777 $DIR/$tfile
7552         chmod ug+s $DIR/$tfile
7553         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7554                 error "$RUNAS dd $DIR/$tfile failed"
7555         # See if we are still setuid/sgid
7556         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7557                 error "S/gid is not dropped on write"
7558         # Now test that MDS is updated too
7559         cancel_lru_locks mdc
7560         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7561                 error "S/gid is not dropped on MDS"
7562         rm -f $DIR/$tfile
7563 }
7564 run_test 72a "Test that remove suid works properly (bug5695) ===="
7565
7566 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7567         local perm
7568
7569         [ "$RUNAS_ID" = "$UID" ] &&
7570                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7571         [ "$RUNAS_ID" -eq 0 ] &&
7572                 skip_env "RUNAS_ID = 0 -- skipping"
7573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7574         # Check that testing environment is properly set up. Skip if not
7575         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7576                 skip_env "User $RUNAS_ID does not exist - skipping"
7577
7578         touch $DIR/${tfile}-f{g,u}
7579         test_mkdir $DIR/${tfile}-dg
7580         test_mkdir $DIR/${tfile}-du
7581         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7582         chmod g+s $DIR/${tfile}-{f,d}g
7583         chmod u+s $DIR/${tfile}-{f,d}u
7584         for perm in 777 2777 4777; do
7585                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7586                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7587                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7588                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7589         done
7590         true
7591 }
7592 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7593
7594 # bug 3462 - multiple simultaneous MDC requests
7595 test_73() {
7596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7597
7598         test_mkdir $DIR/d73-1
7599         test_mkdir $DIR/d73-2
7600         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7601         pid1=$!
7602
7603         lctl set_param fail_loc=0x80000129
7604         $MULTIOP $DIR/d73-1/f73-2 Oc &
7605         sleep 1
7606         lctl set_param fail_loc=0
7607
7608         $MULTIOP $DIR/d73-2/f73-3 Oc &
7609         pid3=$!
7610
7611         kill -USR1 $pid1
7612         wait $pid1 || return 1
7613
7614         sleep 25
7615
7616         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7617         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7618         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7619
7620         rm -rf $DIR/d73-*
7621 }
7622 run_test 73 "multiple MDC requests (should not deadlock)"
7623
7624 test_74a() { # bug 6149, 6184
7625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7626
7627         touch $DIR/f74a
7628         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7629         #
7630         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7631         # will spin in a tight reconnection loop
7632         $LCTL set_param fail_loc=0x8000030e
7633         # get any lock that won't be difficult - lookup works.
7634         ls $DIR/f74a
7635         $LCTL set_param fail_loc=0
7636         rm -f $DIR/f74a
7637         true
7638 }
7639 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7640
7641 test_74b() { # bug 13310
7642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7643
7644         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7645         #
7646         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7647         # will spin in a tight reconnection loop
7648         $LCTL set_param fail_loc=0x8000030e
7649         # get a "difficult" lock
7650         touch $DIR/f74b
7651         $LCTL set_param fail_loc=0
7652         rm -f $DIR/f74b
7653         true
7654 }
7655 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7656
7657 test_74c() {
7658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7659
7660         #define OBD_FAIL_LDLM_NEW_LOCK
7661         $LCTL set_param fail_loc=0x319
7662         touch $DIR/$tfile && error "touch successful"
7663         $LCTL set_param fail_loc=0
7664         true
7665 }
7666 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7667
7668 num_inodes() {
7669         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7670 }
7671
7672 test_76() { # Now for bug 20433, added originally in bug 1443
7673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7674
7675         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7676
7677         cancel_lru_locks osc
7678         BEFORE_INODES=$(num_inodes)
7679         echo "before inodes: $BEFORE_INODES"
7680         local COUNT=1000
7681         [ "$SLOW" = "no" ] && COUNT=100
7682         for i in $(seq $COUNT); do
7683                 touch $DIR/$tfile
7684                 rm -f $DIR/$tfile
7685         done
7686         cancel_lru_locks osc
7687         AFTER_INODES=$(num_inodes)
7688         echo "after inodes: $AFTER_INODES"
7689         local wait=0
7690         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7691                 sleep 2
7692                 AFTER_INODES=$(num_inodes)
7693                 wait=$((wait+2))
7694                 echo "wait $wait seconds inodes: $AFTER_INODES"
7695                 if [ $wait -gt 30 ]; then
7696                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7697                 fi
7698         done
7699 }
7700 run_test 76 "confirm clients recycle inodes properly ===="
7701
7702
7703 export ORIG_CSUM=""
7704 set_checksums()
7705 {
7706         # Note: in sptlrpc modes which enable its own bulk checksum, the
7707         # original crc32_le bulk checksum will be automatically disabled,
7708         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7709         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7710         # In this case set_checksums() will not be no-op, because sptlrpc
7711         # bulk checksum will be enabled all through the test.
7712
7713         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7714         lctl set_param -n osc.*.checksums $1
7715         return 0
7716 }
7717
7718 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7719                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7720 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7721                              tr -d [] | head -n1)}
7722 set_checksum_type()
7723 {
7724         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7725         log "set checksum type to $1"
7726         return 0
7727 }
7728 F77_TMP=$TMP/f77-temp
7729 F77SZ=8
7730 setup_f77() {
7731         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7732                 error "error writing to $F77_TMP"
7733 }
7734
7735 test_77a() { # bug 10889
7736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7737         $GSS && skip_env "could not run with gss"
7738
7739         [ ! -f $F77_TMP ] && setup_f77
7740         set_checksums 1
7741         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7742         set_checksums 0
7743         rm -f $DIR/$tfile
7744 }
7745 run_test 77a "normal checksum read/write operation"
7746
7747 test_77b() { # bug 10889
7748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7749         $GSS && skip_env "could not run with gss"
7750
7751         [ ! -f $F77_TMP ] && setup_f77
7752         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7753         $LCTL set_param fail_loc=0x80000409
7754         set_checksums 1
7755
7756         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7757                 error "dd error: $?"
7758         $LCTL set_param fail_loc=0
7759
7760         for algo in $CKSUM_TYPES; do
7761                 cancel_lru_locks osc
7762                 set_checksum_type $algo
7763                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7764                 $LCTL set_param fail_loc=0x80000408
7765                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7766                 $LCTL set_param fail_loc=0
7767         done
7768         set_checksums 0
7769         set_checksum_type $ORIG_CSUM_TYPE
7770         rm -f $DIR/$tfile
7771 }
7772 run_test 77b "checksum error on client write, read"
7773
7774 cleanup_77c() {
7775         trap 0
7776         set_checksums 0
7777         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7778         $check_ost &&
7779                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7780         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7781         $check_ost && [ -n "$ost_file_prefix" ] &&
7782                 do_facet ost1 rm -f ${ost_file_prefix}\*
7783 }
7784
7785 test_77c() {
7786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7787         $GSS && skip_env "could not run with gss"
7788         remote_ost_nodsh && skip "remote OST with nodsh"
7789
7790         local bad1
7791         local osc_file_prefix
7792         local osc_file
7793         local check_ost=false
7794         local ost_file_prefix
7795         local ost_file
7796         local orig_cksum
7797         local dump_cksum
7798         local fid
7799
7800         # ensure corruption will occur on first OSS/OST
7801         $LFS setstripe -i 0 $DIR/$tfile
7802
7803         [ ! -f $F77_TMP ] && setup_f77
7804         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7805                 error "dd write error: $?"
7806         fid=$($LFS path2fid $DIR/$tfile)
7807
7808         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7809         then
7810                 check_ost=true
7811                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7812                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7813         else
7814                 echo "OSS do not support bulk pages dump upon error"
7815         fi
7816
7817         osc_file_prefix=$($LCTL get_param -n debug_path)
7818         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7819
7820         trap cleanup_77c EXIT
7821
7822         set_checksums 1
7823         # enable bulk pages dump upon error on Client
7824         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7825         # enable bulk pages dump upon error on OSS
7826         $check_ost &&
7827                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7828
7829         # flush Client cache to allow next read to reach OSS
7830         cancel_lru_locks osc
7831
7832         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7833         $LCTL set_param fail_loc=0x80000408
7834         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7835         $LCTL set_param fail_loc=0
7836
7837         rm -f $DIR/$tfile
7838
7839         # check cksum dump on Client
7840         osc_file=$(ls ${osc_file_prefix}*)
7841         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7842         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7843         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7844         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7845         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7846                      cksum)
7847         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7848         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7849                 error "dump content does not match on Client"
7850
7851         $check_ost || skip "No need to check cksum dump on OSS"
7852
7853         # check cksum dump on OSS
7854         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7855         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7856         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7857         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7858         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7859                 error "dump content does not match on OSS"
7860
7861         cleanup_77c
7862 }
7863 run_test 77c "checksum error on client read with debug"
7864
7865 test_77d() { # bug 10889
7866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7867         $GSS && skip_env "could not run with gss"
7868
7869         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7870         $LCTL set_param fail_loc=0x80000409
7871         set_checksums 1
7872         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7873                 error "direct write: rc=$?"
7874         $LCTL set_param fail_loc=0
7875         set_checksums 0
7876
7877         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7878         $LCTL set_param fail_loc=0x80000408
7879         set_checksums 1
7880         cancel_lru_locks osc
7881         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7882                 error "direct read: rc=$?"
7883         $LCTL set_param fail_loc=0
7884         set_checksums 0
7885 }
7886 run_test 77d "checksum error on OST direct write, read"
7887
7888 test_77f() { # bug 10889
7889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7890         $GSS && skip_env "could not run with gss"
7891
7892         set_checksums 1
7893         for algo in $CKSUM_TYPES; do
7894                 cancel_lru_locks osc
7895                 set_checksum_type $algo
7896                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7897                 $LCTL set_param fail_loc=0x409
7898                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7899                         error "direct write succeeded"
7900                 $LCTL set_param fail_loc=0
7901         done
7902         set_checksum_type $ORIG_CSUM_TYPE
7903         set_checksums 0
7904 }
7905 run_test 77f "repeat checksum error on write (expect error)"
7906
7907 test_77g() { # bug 10889
7908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7909         $GSS && skip_env "could not run with gss"
7910         remote_ost_nodsh && skip "remote OST with nodsh"
7911
7912         [ ! -f $F77_TMP ] && setup_f77
7913
7914         local file=$DIR/$tfile
7915         stack_trap "rm -f $file" EXIT
7916
7917         $LFS setstripe -c 1 -i 0 $file
7918         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7919         do_facet ost1 lctl set_param fail_loc=0x8000021a
7920         set_checksums 1
7921         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7922                 error "write error: rc=$?"
7923         do_facet ost1 lctl set_param fail_loc=0
7924         set_checksums 0
7925
7926         cancel_lru_locks osc
7927         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7928         do_facet ost1 lctl set_param fail_loc=0x8000021b
7929         set_checksums 1
7930         cmp $F77_TMP $file || error "file compare failed"
7931         do_facet ost1 lctl set_param fail_loc=0
7932         set_checksums 0
7933 }
7934 run_test 77g "checksum error on OST write, read"
7935
7936 test_77k() { # LU-10906
7937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7938         $GSS && skip_env "could not run with gss"
7939
7940         local cksum_param="osc.$FSNAME*.checksums"
7941         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7942         local checksum
7943         local i
7944
7945         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7946         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7947         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7948                 EXIT
7949
7950         for i in 0 1; do
7951                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7952                         error "failed to set checksum=$i on MGS"
7953                 wait_update $HOSTNAME "$get_checksum" $i
7954                 #remount
7955                 echo "remount client, checksum should be $i"
7956                 remount_client $MOUNT || "failed to remount client"
7957                 checksum=$(eval $get_checksum)
7958                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7959         done
7960         # remove persistent param to avoid races with checksum mountopt below
7961         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7962                 error "failed to delete checksum on MGS"
7963
7964         for opt in "checksum" "nochecksum"; do
7965                 #remount with mount option
7966                 echo "remount client with option $opt, checksum should be $i"
7967                 umount_client $MOUNT || "failed to umount client"
7968                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7969                         "failed to mount client with option '$opt'"
7970                 checksum=$(eval $get_checksum)
7971                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7972                 i=$((i - 1))
7973         done
7974
7975         remount_client $MOUNT || "failed to remount client"
7976 }
7977 run_test 77k "enable/disable checksum correctly"
7978
7979 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7980 rm -f $F77_TMP
7981 unset F77_TMP
7982
7983 cleanup_test_78() {
7984         trap 0
7985         rm -f $DIR/$tfile
7986 }
7987
7988 test_78() { # bug 10901
7989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7990         remote_ost || skip_env "local OST"
7991
7992         NSEQ=5
7993         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
7994         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
7995         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
7996         echo "MemTotal: $MEMTOTAL"
7997
7998         # reserve 256MB of memory for the kernel and other running processes,
7999         # and then take 1/2 of the remaining memory for the read/write buffers.
8000         if [ $MEMTOTAL -gt 512 ] ;then
8001                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8002         else
8003                 # for those poor memory-starved high-end clusters...
8004                 MEMTOTAL=$((MEMTOTAL / 2))
8005         fi
8006         echo "Mem to use for directio: $MEMTOTAL"
8007
8008         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8009         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8010         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8011         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8012                 head -n1)
8013         echo "Smallest OST: $SMALLESTOST"
8014         [[ $SMALLESTOST -lt 10240 ]] &&
8015                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8016
8017         trap cleanup_test_78 EXIT
8018
8019         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8020                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8021
8022         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8023         echo "File size: $F78SIZE"
8024         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8025         for i in $(seq 1 $NSEQ); do
8026                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8027                 echo directIO rdwr round $i of $NSEQ
8028                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8029         done
8030
8031         cleanup_test_78
8032 }
8033 run_test 78 "handle large O_DIRECT writes correctly ============"
8034
8035 test_79() { # bug 12743
8036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8037
8038         wait_delete_completed
8039
8040         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8041         BKFREE=$(calc_osc_kbytes kbytesfree)
8042         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8043
8044         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8045         DFTOTAL=`echo $STRING | cut -d, -f1`
8046         DFUSED=`echo $STRING  | cut -d, -f2`
8047         DFAVAIL=`echo $STRING | cut -d, -f3`
8048         DFFREE=$(($DFTOTAL - $DFUSED))
8049
8050         ALLOWANCE=$((64 * $OSTCOUNT))
8051
8052         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8053            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8054                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8055         fi
8056         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8057            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8058                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8059         fi
8060         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8061            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8062                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8063         fi
8064 }
8065 run_test 79 "df report consistency check ======================="
8066
8067 test_80() { # bug 10718
8068         remote_ost_nodsh && skip "remote OST with nodsh"
8069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8070
8071         # relax strong synchronous semantics for slow backends like ZFS
8072         local soc="obdfilter.*.sync_on_lock_cancel"
8073         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8074         local hosts=
8075         if [ "$soc_old" != "never" ] &&
8076                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8077                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8078                                 facet_active_host $host; done | sort -u)
8079                         do_nodes $hosts lctl set_param $soc=never
8080         fi
8081
8082         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8083         sync; sleep 1; sync
8084         local BEFORE=`date +%s`
8085         cancel_lru_locks osc
8086         local AFTER=`date +%s`
8087         local DIFF=$((AFTER-BEFORE))
8088         if [ $DIFF -gt 1 ] ; then
8089                 error "elapsed for 1M@1T = $DIFF"
8090         fi
8091
8092         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8093
8094         rm -f $DIR/$tfile
8095 }
8096 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8097
8098 test_81a() { # LU-456
8099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8100         remote_ost_nodsh && skip "remote OST with nodsh"
8101
8102         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8103         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8104         do_facet ost1 lctl set_param fail_loc=0x80000228
8105
8106         # write should trigger a retry and success
8107         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8108         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8109         RC=$?
8110         if [ $RC -ne 0 ] ; then
8111                 error "write should success, but failed for $RC"
8112         fi
8113 }
8114 run_test 81a "OST should retry write when get -ENOSPC ==============="
8115
8116 test_81b() { # LU-456
8117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8118         remote_ost_nodsh && skip "remote OST with nodsh"
8119
8120         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8121         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8122         do_facet ost1 lctl set_param fail_loc=0x228
8123
8124         # write should retry several times and return -ENOSPC finally
8125         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8126         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8127         RC=$?
8128         ENOSPC=28
8129         if [ $RC -ne $ENOSPC ] ; then
8130                 error "dd should fail for -ENOSPC, but succeed."
8131         fi
8132 }
8133 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8134
8135 test_82() { # LU-1031
8136         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8137         local gid1=14091995
8138         local gid2=16022000
8139
8140         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8141         local MULTIPID1=$!
8142         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8143         local MULTIPID2=$!
8144         kill -USR1 $MULTIPID2
8145         sleep 2
8146         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8147                 error "First grouplock does not block second one"
8148         else
8149                 echo "Second grouplock blocks first one"
8150         fi
8151         kill -USR1 $MULTIPID1
8152         wait $MULTIPID1
8153         wait $MULTIPID2
8154 }
8155 run_test 82 "Basic grouplock test"
8156
8157 test_99() {
8158         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8159
8160         test_mkdir $DIR/$tdir.cvsroot
8161         chown $RUNAS_ID $DIR/$tdir.cvsroot
8162
8163         cd $TMP
8164         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8165
8166         cd /etc/init.d
8167         # some versions of cvs import exit(1) when asked to import links or
8168         # files they can't read.  ignore those files.
8169         local toignore=$(find . -type l -printf '-I %f\n' -o \
8170                          ! -perm /4 -printf '-I %f\n')
8171         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8172                 $tdir.reposname vtag rtag
8173
8174         cd $DIR
8175         test_mkdir $DIR/$tdir.reposname
8176         chown $RUNAS_ID $DIR/$tdir.reposname
8177         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8178
8179         cd $DIR/$tdir.reposname
8180         $RUNAS touch foo99
8181         $RUNAS cvs add -m 'addmsg' foo99
8182         $RUNAS cvs update
8183         $RUNAS cvs commit -m 'nomsg' foo99
8184         rm -fr $DIR/$tdir.cvsroot
8185 }
8186 run_test 99 "cvs strange file/directory operations"
8187
8188 test_100() {
8189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8190         [[ "$NETTYPE" =~ tcp ]] ||
8191                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8192         remote_ost_nodsh && skip "remote OST with nodsh"
8193         remote_mds_nodsh && skip "remote MDS with nodsh"
8194         remote_servers ||
8195                 skip "useless for local single node setup"
8196
8197         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8198                 [ "$PROT" != "tcp" ] && continue
8199                 RPORT=$(echo $REMOTE | cut -d: -f2)
8200                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8201
8202                 rc=0
8203                 LPORT=`echo $LOCAL | cut -d: -f2`
8204                 if [ $LPORT -ge 1024 ]; then
8205                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8206                         netstat -tna
8207                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8208                 fi
8209         done
8210         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8211 }
8212 run_test 100 "check local port using privileged port ==========="
8213
8214 function get_named_value()
8215 {
8216     local tag
8217
8218     tag=$1
8219     while read ;do
8220         line=$REPLY
8221         case $line in
8222         $tag*)
8223             echo $line | sed "s/^$tag[ ]*//"
8224             break
8225             ;;
8226         esac
8227     done
8228 }
8229
8230 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8231                    awk '/^max_cached_mb/ { print $2 }')
8232
8233 cleanup_101a() {
8234         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8235         trap 0
8236 }
8237
8238 test_101a() {
8239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8240         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
8241
8242         local s
8243         local discard
8244         local nreads=10000
8245         local cache_limit=32
8246
8247         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8248         trap cleanup_101a EXIT
8249         $LCTL set_param -n llite.*.read_ahead_stats 0
8250         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8251
8252         #
8253         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8254         #
8255         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8256         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8257
8258         discard=0
8259         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8260                 get_named_value 'read but discarded' | cut -d" " -f1); do
8261                         discard=$(($discard + $s))
8262         done
8263         cleanup_101a
8264
8265         if [[ $(($discard * 10)) -gt $nreads ]]; then
8266                 $LCTL get_param osc.*-osc*.rpc_stats
8267                 $LCTL get_param llite.*.read_ahead_stats
8268                 error "too many ($discard) discarded pages"
8269         fi
8270         rm -f $DIR/$tfile || true
8271 }
8272 run_test 101a "check read-ahead for random reads"
8273
8274 setup_test101bc() {
8275         test_mkdir $DIR/$tdir
8276         local ssize=$1
8277         local FILE_LENGTH=$2
8278         STRIPE_OFFSET=0
8279
8280         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8281
8282         local list=$(comma_list $(osts_nodes))
8283         set_osd_param $list '' read_cache_enable 0
8284         set_osd_param $list '' writethrough_cache_enable 0
8285
8286         trap cleanup_test101bc EXIT
8287         # prepare the read-ahead file
8288         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8289
8290         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8291                                 count=$FILE_SIZE_MB 2> /dev/null
8292
8293 }
8294
8295 cleanup_test101bc() {
8296         trap 0
8297         rm -rf $DIR/$tdir
8298         rm -f $DIR/$tfile
8299
8300         local list=$(comma_list $(osts_nodes))
8301         set_osd_param $list '' read_cache_enable 1
8302         set_osd_param $list '' writethrough_cache_enable 1
8303 }
8304
8305 calc_total() {
8306         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8307 }
8308
8309 ra_check_101() {
8310         local READ_SIZE=$1
8311         local STRIPE_SIZE=$2
8312         local FILE_LENGTH=$3
8313         local RA_INC=1048576
8314         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8315         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8316                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8317         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8318                         get_named_value 'read but discarded' |
8319                         cut -d" " -f1 | calc_total)
8320         if [[ $DISCARD -gt $discard_limit ]]; then
8321                 $LCTL get_param llite.*.read_ahead_stats
8322                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8323         else
8324                 echo "Read-ahead success for size ${READ_SIZE}"
8325         fi
8326 }
8327
8328 test_101b() {
8329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8330         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8331
8332         local STRIPE_SIZE=1048576
8333         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8334
8335         if [ $SLOW == "yes" ]; then
8336                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8337         else
8338                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8339         fi
8340
8341         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8342
8343         # prepare the read-ahead file
8344         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8345         cancel_lru_locks osc
8346         for BIDX in 2 4 8 16 32 64 128 256
8347         do
8348                 local BSIZE=$((BIDX*4096))
8349                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8350                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8351                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8352                 $LCTL set_param -n llite.*.read_ahead_stats 0
8353                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8354                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8355                 cancel_lru_locks osc
8356                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8357         done
8358         cleanup_test101bc
8359         true
8360 }
8361 run_test 101b "check stride-io mode read-ahead ================="
8362
8363 test_101c() {
8364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8365
8366         local STRIPE_SIZE=1048576
8367         local FILE_LENGTH=$((STRIPE_SIZE*100))
8368         local nreads=10000
8369         local rsize=65536
8370         local osc_rpc_stats
8371
8372         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8373
8374         cancel_lru_locks osc
8375         $LCTL set_param osc.*.rpc_stats 0
8376         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8377         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8378                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8379                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8380                 local size
8381
8382                 if [ $lines -le 20 ]; then
8383                         continue
8384                 fi
8385                 for size in 1 2 4 8; do
8386                         local rpc=$(echo "$stats" |
8387                                     awk '($1 == "'$size':") {print $2; exit; }')
8388                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8389                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8390                 done
8391                 echo "$osc_rpc_stats check passed!"
8392         done
8393         cleanup_test101bc
8394         true
8395 }
8396 run_test 101c "check stripe_size aligned read-ahead ================="
8397
8398 set_read_ahead() {
8399         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8400         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8401 }
8402
8403 test_101d() {
8404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8405
8406         local file=$DIR/$tfile
8407         local sz_MB=${FILESIZE_101d:-500}
8408         local ra_MB=${READAHEAD_MB:-40}
8409
8410         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8411         [ $free_MB -lt $sz_MB ] &&
8412                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8413
8414         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8415         $LFS setstripe -c -1 $file || error "setstripe failed"
8416
8417         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8418         echo Cancel LRU locks on lustre client to flush the client cache
8419         cancel_lru_locks osc
8420
8421         echo Disable read-ahead
8422         local old_READAHEAD=$(set_read_ahead 0)
8423
8424         echo Reading the test file $file with read-ahead disabled
8425         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8426
8427         echo Cancel LRU locks on lustre client to flush the client cache
8428         cancel_lru_locks osc
8429         echo Enable read-ahead with ${ra_MB}MB
8430         set_read_ahead $ra_MB
8431
8432         echo Reading the test file $file with read-ahead enabled
8433         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8434
8435         echo "read-ahead disabled time read $raOFF"
8436         echo "read-ahead enabled  time read $raON"
8437
8438         set_read_ahead $old_READAHEAD
8439         rm -f $file
8440         wait_delete_completed
8441
8442         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8443                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8444 }
8445 run_test 101d "file read with and without read-ahead enabled"
8446
8447 test_101e() {
8448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8449
8450         local file=$DIR/$tfile
8451         local size_KB=500  #KB
8452         local count=100
8453         local bsize=1024
8454
8455         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8456         local need_KB=$((count * size_KB))
8457         [[ $free_KB -le $need_KB ]] &&
8458                 skip_env "Need free space $need_KB, have $free_KB"
8459
8460         echo "Creating $count ${size_KB}K test files"
8461         for ((i = 0; i < $count; i++)); do
8462                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8463         done
8464
8465         echo "Cancel LRU locks on lustre client to flush the client cache"
8466         cancel_lru_locks $OSC
8467
8468         echo "Reset readahead stats"
8469         $LCTL set_param -n llite.*.read_ahead_stats 0
8470
8471         for ((i = 0; i < $count; i++)); do
8472                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8473         done
8474
8475         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8476                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8477
8478         for ((i = 0; i < $count; i++)); do
8479                 rm -rf $file.$i 2>/dev/null
8480         done
8481
8482         #10000 means 20% reads are missing in readahead
8483         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8484 }
8485 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8486
8487 test_101f() {
8488         which iozone || skip_env "no iozone installed"
8489
8490         local old_debug=$($LCTL get_param debug)
8491         old_debug=${old_debug#*=}
8492         $LCTL set_param debug="reada mmap"
8493
8494         # create a test file
8495         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8496
8497         echo Cancel LRU locks on lustre client to flush the client cache
8498         cancel_lru_locks osc
8499
8500         echo Reset readahead stats
8501         $LCTL set_param -n llite.*.read_ahead_stats 0
8502
8503         echo mmap read the file with small block size
8504         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8505                 > /dev/null 2>&1
8506
8507         echo checking missing pages
8508         $LCTL get_param llite.*.read_ahead_stats
8509         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8510                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8511
8512         $LCTL set_param debug="$old_debug"
8513         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8514         rm -f $DIR/$tfile
8515 }
8516 run_test 101f "check mmap read performance"
8517
8518 test_101g_brw_size_test() {
8519         local mb=$1
8520         local pages=$((mb * 1048576 / PAGE_SIZE))
8521         local file=$DIR/$tfile
8522
8523         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8524                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8525         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8526                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8527                         return 2
8528         done
8529
8530         stack_trap "rm -f $file" EXIT
8531         $LCTL set_param -n osc.*.rpc_stats=0
8532
8533         # 10 RPCs should be enough for the test
8534         local count=10
8535         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8536                 { error "dd write ${mb} MB blocks failed"; return 3; }
8537         cancel_lru_locks osc
8538         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8539                 { error "dd write ${mb} MB blocks failed"; return 4; }
8540
8541         # calculate number of full-sized read and write RPCs
8542         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8543                 sed -n '/pages per rpc/,/^$/p' |
8544                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8545                 END { print reads,writes }'))
8546         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8547                 return 5
8548         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8549                 return 6
8550
8551         return 0
8552 }
8553
8554 test_101g() {
8555         remote_ost_nodsh && skip "remote OST with nodsh"
8556
8557         local rpcs
8558         local osts=$(get_facets OST)
8559         local list=$(comma_list $(osts_nodes))
8560         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8561         local brw_size="obdfilter.*.brw_size"
8562
8563         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8564
8565         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8566
8567         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8568                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8569                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8570            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8571                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8572                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8573
8574                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8575                         suffix="M"
8576
8577                 if [[ $orig_mb -lt 16 ]]; then
8578                         save_lustre_params $osts "$brw_size" > $p
8579                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8580                                 error "set 16MB RPC size failed"
8581
8582                         echo "remount client to enable new RPC size"
8583                         remount_client $MOUNT || error "remount_client failed"
8584                 fi
8585
8586                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8587                 # should be able to set brw_size=12, but no rpc_stats for that
8588                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8589         fi
8590
8591         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8592
8593         if [[ $orig_mb -lt 16 ]]; then
8594                 restore_lustre_params < $p
8595                 remount_client $MOUNT || error "remount_client restore failed"
8596         fi
8597
8598         rm -f $p $DIR/$tfile
8599 }
8600 run_test 101g "Big bulk(4/16 MiB) readahead"
8601
8602 setup_test102() {
8603         test_mkdir $DIR/$tdir
8604         chown $RUNAS_ID $DIR/$tdir
8605         STRIPE_SIZE=65536
8606         STRIPE_OFFSET=1
8607         STRIPE_COUNT=$OSTCOUNT
8608         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8609
8610         trap cleanup_test102 EXIT
8611         cd $DIR
8612         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8613         cd $DIR/$tdir
8614         for num in 1 2 3 4; do
8615                 for count in $(seq 1 $STRIPE_COUNT); do
8616                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8617                                 local size=`expr $STRIPE_SIZE \* $num`
8618                                 local file=file"$num-$idx-$count"
8619                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8620                         done
8621                 done
8622         done
8623
8624         cd $DIR
8625         $1 tar cf $TMP/f102.tar $tdir --xattrs
8626 }
8627
8628 cleanup_test102() {
8629         trap 0
8630         rm -f $TMP/f102.tar
8631         rm -rf $DIR/d0.sanity/d102
8632 }
8633
8634 test_102a() {
8635         [ "$UID" != 0 ] && skip "must run as root"
8636         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8637                 skip_env "must have user_xattr"
8638
8639         [ -z "$(which setfattr 2>/dev/null)" ] &&
8640                 skip_env "could not find setfattr"
8641
8642         local testfile=$DIR/$tfile
8643
8644         touch $testfile
8645         echo "set/get xattr..."
8646         setfattr -n trusted.name1 -v value1 $testfile ||
8647                 error "setfattr -n trusted.name1=value1 $testfile failed"
8648         getfattr -n trusted.name1 $testfile 2> /dev/null |
8649           grep "trusted.name1=.value1" ||
8650                 error "$testfile missing trusted.name1=value1"
8651
8652         setfattr -n user.author1 -v author1 $testfile ||
8653                 error "setfattr -n user.author1=author1 $testfile failed"
8654         getfattr -n user.author1 $testfile 2> /dev/null |
8655           grep "user.author1=.author1" ||
8656                 error "$testfile missing trusted.author1=author1"
8657
8658         echo "listxattr..."
8659         setfattr -n trusted.name2 -v value2 $testfile ||
8660                 error "$testfile unable to set trusted.name2"
8661         setfattr -n trusted.name3 -v value3 $testfile ||
8662                 error "$testfile unable to set trusted.name3"
8663         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8664             grep "trusted.name" | wc -l) -eq 3 ] ||
8665                 error "$testfile missing 3 trusted.name xattrs"
8666
8667         setfattr -n user.author2 -v author2 $testfile ||
8668                 error "$testfile unable to set user.author2"
8669         setfattr -n user.author3 -v author3 $testfile ||
8670                 error "$testfile unable to set user.author3"
8671         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8672             grep "user.author" | wc -l) -eq 3 ] ||
8673                 error "$testfile missing 3 user.author xattrs"
8674
8675         echo "remove xattr..."
8676         setfattr -x trusted.name1 $testfile ||
8677                 error "$testfile error deleting trusted.name1"
8678         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8679                 error "$testfile did not delete trusted.name1 xattr"
8680
8681         setfattr -x user.author1 $testfile ||
8682                 error "$testfile error deleting user.author1"
8683         echo "set lustre special xattr ..."
8684         $LFS setstripe -c1 $testfile
8685         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8686                 awk -F "=" '/trusted.lov/ { print $2 }' )
8687         setfattr -n "trusted.lov" -v $lovea $testfile ||
8688                 error "$testfile doesn't ignore setting trusted.lov again"
8689         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8690                 error "$testfile allow setting invalid trusted.lov"
8691         rm -f $testfile
8692 }
8693 run_test 102a "user xattr test =================================="
8694
8695 test_102b() {
8696         [ -z "$(which setfattr 2>/dev/null)" ] &&
8697                 skip_env "could not find setfattr"
8698         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8699
8700         # b10930: get/set/list trusted.lov xattr
8701         echo "get/set/list trusted.lov xattr ..."
8702         local testfile=$DIR/$tfile
8703         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8704                 error "setstripe failed"
8705         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8706                 error "getstripe failed"
8707         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8708                 error "can't get trusted.lov from $testfile"
8709
8710         local testfile2=${testfile}2
8711         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8712                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8713
8714         $MCREATE $testfile2
8715         setfattr -n trusted.lov -v $value $testfile2
8716         local stripe_size=$($LFS getstripe -S $testfile2)
8717         local stripe_count=$($LFS getstripe -c $testfile2)
8718         [[ $stripe_size -eq 65536 ]] ||
8719                 error "stripe size $stripe_size != 65536"
8720         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8721                 error "stripe count $stripe_count != $STRIPECOUNT"
8722         rm -f $DIR/$tfile
8723 }
8724 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8725
8726 test_102c() {
8727         [ -z "$(which setfattr 2>/dev/null)" ] &&
8728                 skip_env "could not find setfattr"
8729         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8730
8731         # b10930: get/set/list lustre.lov xattr
8732         echo "get/set/list lustre.lov xattr ..."
8733         test_mkdir $DIR/$tdir
8734         chown $RUNAS_ID $DIR/$tdir
8735         local testfile=$DIR/$tdir/$tfile
8736         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8737                 error "setstripe failed"
8738         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8739                 error "getstripe failed"
8740         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8741         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8742
8743         local testfile2=${testfile}2
8744         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8745                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8746
8747         $RUNAS $MCREATE $testfile2
8748         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8749         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8750         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8751         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8752         [ $stripe_count -eq $STRIPECOUNT ] ||
8753                 error "stripe count $stripe_count != $STRIPECOUNT"
8754 }
8755 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8756
8757 compare_stripe_info1() {
8758         local stripe_index_all_zero=true
8759
8760         for num in 1 2 3 4; do
8761                 for count in $(seq 1 $STRIPE_COUNT); do
8762                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8763                                 local size=$((STRIPE_SIZE * num))
8764                                 local file=file"$num-$offset-$count"
8765                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8766                                 [[ $stripe_size -ne $size ]] &&
8767                                     error "$file: size $stripe_size != $size"
8768                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8769                                 # allow fewer stripes to be created, ORI-601
8770                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8771                                     error "$file: count $stripe_count != $count"
8772                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8773                                 [[ $stripe_index -ne 0 ]] &&
8774                                         stripe_index_all_zero=false
8775                         done
8776                 done
8777         done
8778         $stripe_index_all_zero &&
8779                 error "all files are being extracted starting from OST index 0"
8780         return 0
8781 }
8782
8783 have_xattrs_include() {
8784         tar --help | grep -q xattrs-include &&
8785                 echo --xattrs-include="lustre.*"
8786 }
8787
8788 test_102d() {
8789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8790         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8791
8792         XINC=$(have_xattrs_include)
8793         setup_test102
8794         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8795         cd $DIR/$tdir/$tdir
8796         compare_stripe_info1
8797 }
8798 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8799
8800 test_102f() {
8801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8802         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8803
8804         XINC=$(have_xattrs_include)
8805         setup_test102
8806         test_mkdir $DIR/$tdir.restore
8807         cd $DIR
8808         tar cf - --xattrs $tdir | tar xf - \
8809                 -C $DIR/$tdir.restore --xattrs $XINC
8810         cd $DIR/$tdir.restore/$tdir
8811         compare_stripe_info1
8812 }
8813 run_test 102f "tar copy files, not keep osts"
8814
8815 grow_xattr() {
8816         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8817                 skip "must have user_xattr"
8818         [ -z "$(which setfattr 2>/dev/null)" ] &&
8819                 skip_env "could not find setfattr"
8820         [ -z "$(which getfattr 2>/dev/null)" ] &&
8821                 skip_env "could not find getfattr"
8822
8823         local xsize=${1:-1024}  # in bytes
8824         local file=$DIR/$tfile
8825         local value="$(generate_string $xsize)"
8826         local xbig=trusted.big
8827         local toobig=$2
8828
8829         touch $file
8830         log "save $xbig on $file"
8831         if [ -z "$toobig" ]
8832         then
8833                 setfattr -n $xbig -v $value $file ||
8834                         error "saving $xbig on $file failed"
8835         else
8836                 setfattr -n $xbig -v $value $file &&
8837                         error "saving $xbig on $file succeeded"
8838                 return 0
8839         fi
8840
8841         local orig=$(get_xattr_value $xbig $file)
8842         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8843
8844         local xsml=trusted.sml
8845         log "save $xsml on $file"
8846         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8847
8848         local new=$(get_xattr_value $xbig $file)
8849         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8850
8851         log "grow $xsml on $file"
8852         setfattr -n $xsml -v "$value" $file ||
8853                 error "growing $xsml on $file failed"
8854
8855         new=$(get_xattr_value $xbig $file)
8856         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8857         log "$xbig still valid after growing $xsml"
8858
8859         rm -f $file
8860 }
8861
8862 test_102h() { # bug 15777
8863         grow_xattr 1024
8864 }
8865 run_test 102h "grow xattr from inside inode to external block"
8866
8867 test_102ha() {
8868         large_xattr_enabled || skip_env "ea_inode feature disabled"
8869
8870         echo "setting xattr of max xattr size: $(max_xattr_size)"
8871         grow_xattr $(max_xattr_size)
8872
8873         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8874         echo "This should fail:"
8875         grow_xattr $(($(max_xattr_size) + 10)) 1
8876 }
8877 run_test 102ha "grow xattr from inside inode to external inode"
8878
8879 test_102i() { # bug 17038
8880         [ -z "$(which getfattr 2>/dev/null)" ] &&
8881                 skip "could not find getfattr"
8882
8883         touch $DIR/$tfile
8884         ln -s $DIR/$tfile $DIR/${tfile}link
8885         getfattr -n trusted.lov $DIR/$tfile ||
8886                 error "lgetxattr on $DIR/$tfile failed"
8887         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8888                 grep -i "no such attr" ||
8889                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8890         rm -f $DIR/$tfile $DIR/${tfile}link
8891 }
8892 run_test 102i "lgetxattr test on symbolic link ============"
8893
8894 test_102j() {
8895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8896         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8897
8898         XINC=$(have_xattrs_include)
8899         setup_test102 "$RUNAS"
8900         chown $RUNAS_ID $DIR/$tdir
8901         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8902         cd $DIR/$tdir/$tdir
8903         compare_stripe_info1 "$RUNAS"
8904 }
8905 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8906
8907 test_102k() {
8908         [ -z "$(which setfattr 2>/dev/null)" ] &&
8909                 skip "could not find setfattr"
8910
8911         touch $DIR/$tfile
8912         # b22187 just check that does not crash for regular file.
8913         setfattr -n trusted.lov $DIR/$tfile
8914         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8915         local test_kdir=$DIR/$tdir
8916         test_mkdir $test_kdir
8917         local default_size=$($LFS getstripe -S $test_kdir)
8918         local default_count=$($LFS getstripe -c $test_kdir)
8919         local default_offset=$($LFS getstripe -i $test_kdir)
8920         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8921                 error 'dir setstripe failed'
8922         setfattr -n trusted.lov $test_kdir
8923         local stripe_size=$($LFS getstripe -S $test_kdir)
8924         local stripe_count=$($LFS getstripe -c $test_kdir)
8925         local stripe_offset=$($LFS getstripe -i $test_kdir)
8926         [ $stripe_size -eq $default_size ] ||
8927                 error "stripe size $stripe_size != $default_size"
8928         [ $stripe_count -eq $default_count ] ||
8929                 error "stripe count $stripe_count != $default_count"
8930         [ $stripe_offset -eq $default_offset ] ||
8931                 error "stripe offset $stripe_offset != $default_offset"
8932         rm -rf $DIR/$tfile $test_kdir
8933 }
8934 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8935
8936 test_102l() {
8937         [ -z "$(which getfattr 2>/dev/null)" ] &&
8938                 skip "could not find getfattr"
8939
8940         # LU-532 trusted. xattr is invisible to non-root
8941         local testfile=$DIR/$tfile
8942
8943         touch $testfile
8944
8945         echo "listxattr as user..."
8946         chown $RUNAS_ID $testfile
8947         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8948             grep -q "trusted" &&
8949                 error "$testfile trusted xattrs are user visible"
8950
8951         return 0;
8952 }
8953 run_test 102l "listxattr size test =================================="
8954
8955 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8956         local path=$DIR/$tfile
8957         touch $path
8958
8959         listxattr_size_check $path || error "listattr_size_check $path failed"
8960 }
8961 run_test 102m "Ensure listxattr fails on small bufffer ========"
8962
8963 cleanup_test102
8964
8965 getxattr() { # getxattr path name
8966         # Return the base64 encoding of the value of xattr name on path.
8967         local path=$1
8968         local name=$2
8969
8970         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8971         # file: $path
8972         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8973         #
8974         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8975
8976         getfattr --absolute-names --encoding=base64 --name=$name $path |
8977                 awk -F= -v name=$name '$1 == name {
8978                         print substr($0, index($0, "=") + 1);
8979         }'
8980 }
8981
8982 test_102n() { # LU-4101 mdt: protect internal xattrs
8983         [ -z "$(which setfattr 2>/dev/null)" ] &&
8984                 skip "could not find setfattr"
8985         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
8986         then
8987                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
8988         fi
8989
8990         local file0=$DIR/$tfile.0
8991         local file1=$DIR/$tfile.1
8992         local xattr0=$TMP/$tfile.0
8993         local xattr1=$TMP/$tfile.1
8994         local namelist="lov lma lmv link fid version som hsm"
8995         local name
8996         local value
8997
8998         rm -rf $file0 $file1 $xattr0 $xattr1
8999         touch $file0 $file1
9000
9001         # Get 'before' xattrs of $file1.
9002         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9003
9004         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9005                 namelist+=" lfsck_namespace"
9006         for name in $namelist; do
9007                 # Try to copy xattr from $file0 to $file1.
9008                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9009
9010                 setfattr --name=trusted.$name --value="$value" $file1 ||
9011                         error "setxattr 'trusted.$name' failed"
9012
9013                 # Try to set a garbage xattr.
9014                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9015
9016                 if [[ x$name == "xlov" ]]; then
9017                         setfattr --name=trusted.lov --value="$value" $file1 &&
9018                         error "setxattr invalid 'trusted.lov' success"
9019                 else
9020                         setfattr --name=trusted.$name --value="$value" $file1 ||
9021                                 error "setxattr invalid 'trusted.$name' failed"
9022                 fi
9023
9024                 # Try to remove the xattr from $file1. We don't care if this
9025                 # appears to succeed or fail, we just don't want there to be
9026                 # any changes or crashes.
9027                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9028         done
9029
9030         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9031         then
9032                 name="lfsck_ns"
9033                 # Try to copy xattr from $file0 to $file1.
9034                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9035
9036                 setfattr --name=trusted.$name --value="$value" $file1 ||
9037                         error "setxattr 'trusted.$name' failed"
9038
9039                 # Try to set a garbage xattr.
9040                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9041
9042                 setfattr --name=trusted.$name --value="$value" $file1 ||
9043                         error "setxattr 'trusted.$name' failed"
9044
9045                 # Try to remove the xattr from $file1. We don't care if this
9046                 # appears to succeed or fail, we just don't want there to be
9047                 # any changes or crashes.
9048                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9049         fi
9050
9051         # Get 'after' xattrs of file1.
9052         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9053
9054         if ! diff $xattr0 $xattr1; then
9055                 error "before and after xattrs of '$file1' differ"
9056         fi
9057
9058         rm -rf $file0 $file1 $xattr0 $xattr1
9059
9060         return 0
9061 }
9062 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9063
9064 test_102p() { # LU-4703 setxattr did not check ownership
9065         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9066                 skip "MDS needs to be at least 2.5.56"
9067
9068         local testfile=$DIR/$tfile
9069
9070         touch $testfile
9071
9072         echo "setfacl as user..."
9073         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9074         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9075
9076         echo "setfattr as user..."
9077         setfacl -m "u:$RUNAS_ID:---" $testfile
9078         $RUNAS setfattr -x system.posix_acl_access $testfile
9079         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9080 }
9081 run_test 102p "check setxattr(2) correctly fails without permission"
9082
9083 test_102q() {
9084         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9085                 skip "MDS needs to be at least 2.6.92"
9086
9087         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9088 }
9089 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9090
9091 test_102r() {
9092         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9093                 skip "MDS needs to be at least 2.6.93"
9094
9095         touch $DIR/$tfile || error "touch"
9096         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9097         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9098         rm $DIR/$tfile || error "rm"
9099
9100         #normal directory
9101         mkdir -p $DIR/$tdir || error "mkdir"
9102         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9103         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9104         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9105                 error "$testfile error deleting user.author1"
9106         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9107                 grep "user.$(basename $tdir)" &&
9108                 error "$tdir did not delete user.$(basename $tdir)"
9109         rmdir $DIR/$tdir || error "rmdir"
9110
9111         #striped directory
9112         test_mkdir $DIR/$tdir
9113         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9114         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9115         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9116                 error "$testfile error deleting user.author1"
9117         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9118                 grep "user.$(basename $tdir)" &&
9119                 error "$tdir did not delete user.$(basename $tdir)"
9120         rmdir $DIR/$tdir || error "rm striped dir"
9121 }
9122 run_test 102r "set EAs with empty values"
9123
9124 test_102s() {
9125         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9126                 skip "MDS needs to be at least 2.11.52"
9127
9128         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9129
9130         save_lustre_params client "llite.*.xattr_cache" > $save
9131
9132         for cache in 0 1; do
9133                 lctl set_param llite.*.xattr_cache=$cache
9134
9135                 rm -f $DIR/$tfile
9136                 touch $DIR/$tfile || error "touch"
9137                 for prefix in lustre security system trusted user; do
9138                         # Note getxattr() may fail with 'Operation not
9139                         # supported' or 'No such attribute' depending
9140                         # on prefix and cache.
9141                         getfattr -n $prefix.n102s $DIR/$tfile &&
9142                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9143                 done
9144         done
9145
9146         restore_lustre_params < $save
9147 }
9148 run_test 102s "getting nonexistent xattrs should fail"
9149
9150 test_102t() {
9151         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9152                 skip "MDS needs to be at least 2.11.52"
9153
9154         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9155
9156         save_lustre_params client "llite.*.xattr_cache" > $save
9157
9158         for cache in 0 1; do
9159                 lctl set_param llite.*.xattr_cache=$cache
9160
9161                 for buf_size in 0 256; do
9162                         rm -f $DIR/$tfile
9163                         touch $DIR/$tfile || error "touch"
9164                         setfattr -n user.multiop $DIR/$tfile
9165                         $MULTIOP $DIR/$tfile oa$buf_size ||
9166                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9167                 done
9168         done
9169
9170         restore_lustre_params < $save
9171 }
9172 run_test 102t "zero length xattr values handled correctly"
9173
9174 run_acl_subtest()
9175 {
9176     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9177     return $?
9178 }
9179
9180 test_103a() {
9181         [ "$UID" != 0 ] && skip "must run as root"
9182         $GSS && skip_env "could not run under gss"
9183         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9184                 skip_env "must have acl enabled"
9185         [ -z "$(which setfacl 2>/dev/null)" ] &&
9186                 skip_env "could not find setfacl"
9187         remote_mds_nodsh && skip "remote MDS with nodsh"
9188
9189         gpasswd -a daemon bin                           # LU-5641
9190         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9191
9192         declare -a identity_old
9193
9194         for num in $(seq $MDSCOUNT); do
9195                 switch_identity $num true || identity_old[$num]=$?
9196         done
9197
9198         SAVE_UMASK=$(umask)
9199         umask 0022
9200         mkdir -p $DIR/$tdir
9201         cd $DIR/$tdir
9202
9203         echo "performing cp ..."
9204         run_acl_subtest cp || error "run_acl_subtest cp failed"
9205         echo "performing getfacl-noacl..."
9206         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9207         echo "performing misc..."
9208         run_acl_subtest misc || error  "misc test failed"
9209         echo "performing permissions..."
9210         run_acl_subtest permissions || error "permissions failed"
9211         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9212         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9213                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9214                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9215         then
9216                 echo "performing permissions xattr..."
9217                 run_acl_subtest permissions_xattr ||
9218                         error "permissions_xattr failed"
9219         fi
9220         echo "performing setfacl..."
9221         run_acl_subtest setfacl || error  "setfacl test failed"
9222
9223         # inheritance test got from HP
9224         echo "performing inheritance..."
9225         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9226         chmod +x make-tree || error "chmod +x failed"
9227         run_acl_subtest inheritance || error "inheritance test failed"
9228         rm -f make-tree
9229
9230         echo "LU-974 ignore umask when acl is enabled..."
9231         run_acl_subtest 974 || error "LU-974 umask test failed"
9232         if [ $MDSCOUNT -ge 2 ]; then
9233                 run_acl_subtest 974_remote ||
9234                         error "LU-974 umask test failed under remote dir"
9235         fi
9236
9237         echo "LU-2561 newly created file is same size as directory..."
9238         if [ "$mds1_FSTYPE" != "zfs" ]; then
9239                 run_acl_subtest 2561 || error "LU-2561 test failed"
9240         else
9241                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9242         fi
9243
9244         run_acl_subtest 4924 || error "LU-4924 test failed"
9245
9246         cd $SAVE_PWD
9247         umask $SAVE_UMASK
9248
9249         for num in $(seq $MDSCOUNT); do
9250                 if [ "${identity_old[$num]}" = 1 ]; then
9251                         switch_identity $num false || identity_old[$num]=$?
9252                 fi
9253         done
9254 }
9255 run_test 103a "acl test"
9256
9257 test_103b() {
9258         declare -a pids
9259         local U
9260
9261         for U in {0..511}; do
9262                 {
9263                 local O=$(printf "%04o" $U)
9264
9265                 umask $(printf "%04o" $((511 ^ $O)))
9266                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9267                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9268
9269                 (( $S == ($O & 0666) )) ||
9270                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9271
9272                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9273                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9274                 (( $S == ($O & 0666) )) ||
9275                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9276
9277                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9278                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9279                 (( $S == ($O & 0666) )) ||
9280                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9281                 rm -f $DIR/$tfile.[smp]$0
9282                 } &
9283                 local pid=$!
9284
9285                 # limit the concurrently running threads to 64. LU-11878
9286                 local idx=$((U % 64))
9287                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9288                 pids[idx]=$pid
9289         done
9290         wait
9291 }
9292 run_test 103b "umask lfs setstripe"
9293
9294 test_103c() {
9295         mkdir -p $DIR/$tdir
9296         cp -rp $DIR/$tdir $DIR/$tdir.bak
9297
9298         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9299                 error "$DIR/$tdir shouldn't contain default ACL"
9300         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9301                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9302         true
9303 }
9304 run_test 103c "'cp -rp' won't set empty acl"
9305
9306 test_104a() {
9307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9308
9309         touch $DIR/$tfile
9310         lfs df || error "lfs df failed"
9311         lfs df -ih || error "lfs df -ih failed"
9312         lfs df -h $DIR || error "lfs df -h $DIR failed"
9313         lfs df -i $DIR || error "lfs df -i $DIR failed"
9314         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9315         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9316
9317         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9318         lctl --device %$OSC deactivate
9319         lfs df || error "lfs df with deactivated OSC failed"
9320         lctl --device %$OSC activate
9321         # wait the osc back to normal
9322         wait_osc_import_ready client ost
9323
9324         lfs df || error "lfs df with reactivated OSC failed"
9325         rm -f $DIR/$tfile
9326 }
9327 run_test 104a "lfs df [-ih] [path] test ========================="
9328
9329 test_104b() {
9330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9331         [ $RUNAS_ID -eq $UID ] &&
9332                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9333
9334         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9335                         grep "Permission denied" | wc -l)))
9336         if [ $denied_cnt -ne 0 ]; then
9337                 error "lfs check servers test failed"
9338         fi
9339 }
9340 run_test 104b "$RUNAS lfs check servers test ===================="
9341
9342 test_105a() {
9343         # doesn't work on 2.4 kernels
9344         touch $DIR/$tfile
9345         if $(flock_is_enabled); then
9346                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9347         else
9348                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9349         fi
9350         rm -f $DIR/$tfile
9351 }
9352 run_test 105a "flock when mounted without -o flock test ========"
9353
9354 test_105b() {
9355         touch $DIR/$tfile
9356         if $(flock_is_enabled); then
9357                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9358         else
9359                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9360         fi
9361         rm -f $DIR/$tfile
9362 }
9363 run_test 105b "fcntl when mounted without -o flock test ========"
9364
9365 test_105c() {
9366         touch $DIR/$tfile
9367         if $(flock_is_enabled); then
9368                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9369         else
9370                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9371         fi
9372         rm -f $DIR/$tfile
9373 }
9374 run_test 105c "lockf when mounted without -o flock test"
9375
9376 test_105d() { # bug 15924
9377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9378
9379         test_mkdir $DIR/$tdir
9380         flock_is_enabled || skip_env "mount w/o flock enabled"
9381         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9382         $LCTL set_param fail_loc=0x80000315
9383         flocks_test 2 $DIR/$tdir
9384 }
9385 run_test 105d "flock race (should not freeze) ========"
9386
9387 test_105e() { # bug 22660 && 22040
9388         flock_is_enabled || skip_env "mount w/o flock enabled"
9389
9390         touch $DIR/$tfile
9391         flocks_test 3 $DIR/$tfile
9392 }
9393 run_test 105e "Two conflicting flocks from same process"
9394
9395 test_106() { #bug 10921
9396         test_mkdir $DIR/$tdir
9397         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9398         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9399 }
9400 run_test 106 "attempt exec of dir followed by chown of that dir"
9401
9402 test_107() {
9403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9404
9405         CDIR=`pwd`
9406         local file=core
9407
9408         cd $DIR
9409         rm -f $file
9410
9411         local save_pattern=$(sysctl -n kernel.core_pattern)
9412         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9413         sysctl -w kernel.core_pattern=$file
9414         sysctl -w kernel.core_uses_pid=0
9415
9416         ulimit -c unlimited
9417         sleep 60 &
9418         SLEEPPID=$!
9419
9420         sleep 1
9421
9422         kill -s 11 $SLEEPPID
9423         wait $SLEEPPID
9424         if [ -e $file ]; then
9425                 size=`stat -c%s $file`
9426                 [ $size -eq 0 ] && error "Fail to create core file $file"
9427         else
9428                 error "Fail to create core file $file"
9429         fi
9430         rm -f $file
9431         sysctl -w kernel.core_pattern=$save_pattern
9432         sysctl -w kernel.core_uses_pid=$save_uses_pid
9433         cd $CDIR
9434 }
9435 run_test 107 "Coredump on SIG"
9436
9437 test_110() {
9438         test_mkdir $DIR/$tdir
9439         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9440         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9441                 error "mkdir with 256 char should fail, but did not"
9442         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9443                 error "create with 255 char failed"
9444         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9445                 error "create with 256 char should fail, but did not"
9446
9447         ls -l $DIR/$tdir
9448         rm -rf $DIR/$tdir
9449 }
9450 run_test 110 "filename length checking"
9451
9452 #
9453 # Purpose: To verify dynamic thread (OSS) creation.
9454 #
9455 test_115() {
9456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9457         remote_ost_nodsh && skip "remote OST with nodsh"
9458
9459         # Lustre does not stop service threads once they are started.
9460         # Reset number of running threads to default.
9461         stopall
9462         setupall
9463
9464         local OSTIO_pre
9465         local save_params="$TMP/sanity-$TESTNAME.parameters"
9466
9467         # Get ll_ost_io count before I/O
9468         OSTIO_pre=$(do_facet ost1 \
9469                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9470         # Exit if lustre is not running (ll_ost_io not running).
9471         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9472
9473         echo "Starting with $OSTIO_pre threads"
9474         local thread_max=$((OSTIO_pre * 2))
9475         local rpc_in_flight=$((thread_max * 2))
9476         # Number of I/O Process proposed to be started.
9477         local nfiles
9478         local facets=$(get_facets OST)
9479
9480         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9481         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9482
9483         # Set in_flight to $rpc_in_flight
9484         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9485                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9486         nfiles=${rpc_in_flight}
9487         # Set ost thread_max to $thread_max
9488         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9489
9490         # 5 Minutes should be sufficient for max number of OSS
9491         # threads(thread_max) to be created.
9492         local timeout=300
9493
9494         # Start I/O.
9495         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9496         test_mkdir $DIR/$tdir
9497         for i in $(seq $nfiles); do
9498                 local file=$DIR/$tdir/${tfile}-$i
9499                 $LFS setstripe -c -1 -i 0 $file
9500                 ($WTL $file $timeout)&
9501         done
9502
9503         # I/O Started - Wait for thread_started to reach thread_max or report
9504         # error if thread_started is more than thread_max.
9505         echo "Waiting for thread_started to reach thread_max"
9506         local thread_started=0
9507         local end_time=$((SECONDS + timeout))
9508
9509         while [ $SECONDS -le $end_time ] ; do
9510                 echo -n "."
9511                 # Get ost i/o thread_started count.
9512                 thread_started=$(do_facet ost1 \
9513                         "$LCTL get_param \
9514                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9515                 # Break out if thread_started is equal/greater than thread_max
9516                 if [[ $thread_started -ge $thread_max ]]; then
9517                         echo ll_ost_io thread_started $thread_started, \
9518                                 equal/greater than thread_max $thread_max
9519                         break
9520                 fi
9521                 sleep 1
9522         done
9523
9524         # Cleanup - We have the numbers, Kill i/o jobs if running.
9525         jobcount=($(jobs -p))
9526         for i in $(seq 0 $((${#jobcount[@]}-1)))
9527         do
9528                 kill -9 ${jobcount[$i]}
9529                 if [ $? -ne 0 ] ; then
9530                         echo Warning: \
9531                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9532                 fi
9533         done
9534
9535         # Cleanup files left by WTL binary.
9536         for i in $(seq $nfiles); do
9537                 local file=$DIR/$tdir/${tfile}-$i
9538                 rm -rf $file
9539                 if [ $? -ne 0 ] ; then
9540                         echo "Warning: Failed to delete file $file"
9541                 fi
9542         done
9543
9544         restore_lustre_params <$save_params
9545         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9546
9547         # Error out if no new thread has started or Thread started is greater
9548         # than thread max.
9549         if [[ $thread_started -le $OSTIO_pre ||
9550                         $thread_started -gt $thread_max ]]; then
9551                 error "ll_ost_io: thread_started $thread_started" \
9552                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9553                       "No new thread started or thread started greater " \
9554                       "than thread_max."
9555         fi
9556 }
9557 run_test 115 "verify dynamic thread creation===================="
9558
9559 free_min_max () {
9560         wait_delete_completed
9561         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9562         echo "OST kbytes available: ${AVAIL[@]}"
9563         MAXV=${AVAIL[0]}
9564         MAXI=0
9565         MINV=${AVAIL[0]}
9566         MINI=0
9567         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9568                 #echo OST $i: ${AVAIL[i]}kb
9569                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9570                         MAXV=${AVAIL[i]}
9571                         MAXI=$i
9572                 fi
9573                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9574                         MINV=${AVAIL[i]}
9575                         MINI=$i
9576                 fi
9577         done
9578         echo "Min free space: OST $MINI: $MINV"
9579         echo "Max free space: OST $MAXI: $MAXV"
9580 }
9581
9582 test_116a() { # was previously test_116()
9583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9584         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9585         remote_mds_nodsh && skip "remote MDS with nodsh"
9586
9587         echo -n "Free space priority "
9588         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
9589                 head -n1
9590         declare -a AVAIL
9591         free_min_max
9592
9593         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9594         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9595         trap simple_cleanup_common EXIT
9596
9597         # Check if we need to generate uneven OSTs
9598         test_mkdir -p $DIR/$tdir/OST${MINI}
9599         local FILL=$((MINV / 4))
9600         local DIFF=$((MAXV - MINV))
9601         local DIFF2=$((DIFF * 100 / MINV))
9602
9603         local threshold=$(do_facet $SINGLEMDS \
9604                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9605         threshold=${threshold%%%}
9606         echo -n "Check for uneven OSTs: "
9607         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9608
9609         if [[ $DIFF2 -gt $threshold ]]; then
9610                 echo "ok"
9611                 echo "Don't need to fill OST$MINI"
9612         else
9613                 # generate uneven OSTs. Write 2% over the QOS threshold value
9614                 echo "no"
9615                 DIFF=$((threshold - DIFF2 + 2))
9616                 DIFF2=$((MINV * DIFF / 100))
9617                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9618                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9619                         error "setstripe failed"
9620                 DIFF=$((DIFF2 / 2048))
9621                 i=0
9622                 while [ $i -lt $DIFF ]; do
9623                         i=$((i + 1))
9624                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9625                                 bs=2M count=1 2>/dev/null
9626                         echo -n .
9627                 done
9628                 echo .
9629                 sync
9630                 sleep_maxage
9631                 free_min_max
9632         fi
9633
9634         DIFF=$((MAXV - MINV))
9635         DIFF2=$((DIFF * 100 / MINV))
9636         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9637         if [ $DIFF2 -gt $threshold ]; then
9638                 echo "ok"
9639         else
9640                 echo "failed - QOS mode won't be used"
9641                 simple_cleanup_common
9642                 skip "QOS imbalance criteria not met"
9643         fi
9644
9645         MINI1=$MINI
9646         MINV1=$MINV
9647         MAXI1=$MAXI
9648         MAXV1=$MAXV
9649
9650         # now fill using QOS
9651         $LFS setstripe -c 1 $DIR/$tdir
9652         FILL=$((FILL / 200))
9653         if [ $FILL -gt 600 ]; then
9654                 FILL=600
9655         fi
9656         echo "writing $FILL files to QOS-assigned OSTs"
9657         i=0
9658         while [ $i -lt $FILL ]; do
9659                 i=$((i + 1))
9660                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9661                         count=1 2>/dev/null
9662                 echo -n .
9663         done
9664         echo "wrote $i 200k files"
9665         sync
9666         sleep_maxage
9667
9668         echo "Note: free space may not be updated, so measurements might be off"
9669         free_min_max
9670         DIFF2=$((MAXV - MINV))
9671         echo "free space delta: orig $DIFF final $DIFF2"
9672         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9673         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9674         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9675         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9676         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9677         if [[ $DIFF -gt 0 ]]; then
9678                 FILL=$((DIFF2 * 100 / DIFF - 100))
9679                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9680         fi
9681
9682         # Figure out which files were written where
9683         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9684                awk '/'$MINI1': / {print $2; exit}')
9685         echo $UUID
9686         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9687         echo "$MINC files created on smaller OST $MINI1"
9688         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9689                awk '/'$MAXI1': / {print $2; exit}')
9690         echo $UUID
9691         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9692         echo "$MAXC files created on larger OST $MAXI1"
9693         if [[ $MINC -gt 0 ]]; then
9694                 FILL=$((MAXC * 100 / MINC - 100))
9695                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9696         fi
9697         [[ $MAXC -gt $MINC ]] ||
9698                 error_ignore LU-9 "stripe QOS didn't balance free space"
9699         simple_cleanup_common
9700 }
9701 run_test 116a "stripe QOS: free space balance ==================="
9702
9703 test_116b() { # LU-2093
9704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9705         remote_mds_nodsh && skip "remote MDS with nodsh"
9706
9707 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9708         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9709                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9710         [ -z "$old_rr" ] && skip "no QOS"
9711         do_facet $SINGLEMDS lctl set_param \
9712                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9713         mkdir -p $DIR/$tdir
9714         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9715         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9716         do_facet $SINGLEMDS lctl set_param fail_loc=0
9717         rm -rf $DIR/$tdir
9718         do_facet $SINGLEMDS lctl set_param \
9719                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9720 }
9721 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9722
9723 test_117() # bug 10891
9724 {
9725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9726
9727         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9728         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9729         lctl set_param fail_loc=0x21e
9730         > $DIR/$tfile || error "truncate failed"
9731         lctl set_param fail_loc=0
9732         echo "Truncate succeeded."
9733         rm -f $DIR/$tfile
9734 }
9735 run_test 117 "verify osd extend =========="
9736
9737 NO_SLOW_RESENDCOUNT=4
9738 export OLD_RESENDCOUNT=""
9739 set_resend_count () {
9740         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9741         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9742         lctl set_param -n $PROC_RESENDCOUNT $1
9743         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9744 }
9745
9746 # for reduce test_118* time (b=14842)
9747 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9748
9749 # Reset async IO behavior after error case
9750 reset_async() {
9751         FILE=$DIR/reset_async
9752
9753         # Ensure all OSCs are cleared
9754         $LFS setstripe -c -1 $FILE
9755         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9756         sync
9757         rm $FILE
9758 }
9759
9760 test_118a() #bug 11710
9761 {
9762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9763
9764         reset_async
9765
9766         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9767         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9768         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9769
9770         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9771                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9772                 return 1;
9773         fi
9774         rm -f $DIR/$tfile
9775 }
9776 run_test 118a "verify O_SYNC works =========="
9777
9778 test_118b()
9779 {
9780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9781         remote_ost_nodsh && skip "remote OST with nodsh"
9782
9783         reset_async
9784
9785         #define OBD_FAIL_SRV_ENOENT 0x217
9786         set_nodes_failloc "$(osts_nodes)" 0x217
9787         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9788         RC=$?
9789         set_nodes_failloc "$(osts_nodes)" 0
9790         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9791         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9792                     grep -c writeback)
9793
9794         if [[ $RC -eq 0 ]]; then
9795                 error "Must return error due to dropped pages, rc=$RC"
9796                 return 1;
9797         fi
9798
9799         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9800                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9801                 return 1;
9802         fi
9803
9804         echo "Dirty pages not leaked on ENOENT"
9805
9806         # Due to the above error the OSC will issue all RPCs syncronously
9807         # until a subsequent RPC completes successfully without error.
9808         $MULTIOP $DIR/$tfile Ow4096yc
9809         rm -f $DIR/$tfile
9810
9811         return 0
9812 }
9813 run_test 118b "Reclaim dirty pages on fatal error =========="
9814
9815 test_118c()
9816 {
9817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9818
9819         # for 118c, restore the original resend count, LU-1940
9820         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9821                                 set_resend_count $OLD_RESENDCOUNT
9822         remote_ost_nodsh && skip "remote OST with nodsh"
9823
9824         reset_async
9825
9826         #define OBD_FAIL_OST_EROFS               0x216
9827         set_nodes_failloc "$(osts_nodes)" 0x216
9828
9829         # multiop should block due to fsync until pages are written
9830         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9831         MULTIPID=$!
9832         sleep 1
9833
9834         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9835                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9836         fi
9837
9838         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9839                     grep -c writeback)
9840         if [[ $WRITEBACK -eq 0 ]]; then
9841                 error "No page in writeback, writeback=$WRITEBACK"
9842         fi
9843
9844         set_nodes_failloc "$(osts_nodes)" 0
9845         wait $MULTIPID
9846         RC=$?
9847         if [[ $RC -ne 0 ]]; then
9848                 error "Multiop fsync failed, rc=$RC"
9849         fi
9850
9851         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9852         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9853                     grep -c writeback)
9854         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9855                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9856         fi
9857
9858         rm -f $DIR/$tfile
9859         echo "Dirty pages flushed via fsync on EROFS"
9860         return 0
9861 }
9862 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9863
9864 # continue to use small resend count to reduce test_118* time (b=14842)
9865 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9866
9867 test_118d()
9868 {
9869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9870         remote_ost_nodsh && skip "remote OST with nodsh"
9871
9872         reset_async
9873
9874         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9875         set_nodes_failloc "$(osts_nodes)" 0x214
9876         # multiop should block due to fsync until pages are written
9877         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9878         MULTIPID=$!
9879         sleep 1
9880
9881         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9882                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9883         fi
9884
9885         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9886                     grep -c writeback)
9887         if [[ $WRITEBACK -eq 0 ]]; then
9888                 error "No page in writeback, writeback=$WRITEBACK"
9889         fi
9890
9891         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9892         set_nodes_failloc "$(osts_nodes)" 0
9893
9894         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9895         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9896                     grep -c writeback)
9897         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9898                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9899         fi
9900
9901         rm -f $DIR/$tfile
9902         echo "Dirty pages gaurenteed flushed via fsync"
9903         return 0
9904 }
9905 run_test 118d "Fsync validation inject a delay of the bulk =========="
9906
9907 test_118f() {
9908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9909
9910         reset_async
9911
9912         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9913         lctl set_param fail_loc=0x8000040a
9914
9915         # Should simulate EINVAL error which is fatal
9916         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9917         RC=$?
9918         if [[ $RC -eq 0 ]]; then
9919                 error "Must return error due to dropped pages, rc=$RC"
9920         fi
9921
9922         lctl set_param fail_loc=0x0
9923
9924         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9925         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9926         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9927                     grep -c writeback)
9928         if [[ $LOCKED -ne 0 ]]; then
9929                 error "Locked pages remain in cache, locked=$LOCKED"
9930         fi
9931
9932         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9933                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9934         fi
9935
9936         rm -f $DIR/$tfile
9937         echo "No pages locked after fsync"
9938
9939         reset_async
9940         return 0
9941 }
9942 run_test 118f "Simulate unrecoverable OSC side error =========="
9943
9944 test_118g() {
9945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9946
9947         reset_async
9948
9949         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9950         lctl set_param fail_loc=0x406
9951
9952         # simulate local -ENOMEM
9953         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9954         RC=$?
9955
9956         lctl set_param fail_loc=0
9957         if [[ $RC -eq 0 ]]; then
9958                 error "Must return error due to dropped pages, rc=$RC"
9959         fi
9960
9961         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9962         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9963         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9964                         grep -c writeback)
9965         if [[ $LOCKED -ne 0 ]]; then
9966                 error "Locked pages remain in cache, locked=$LOCKED"
9967         fi
9968
9969         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9970                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9971         fi
9972
9973         rm -f $DIR/$tfile
9974         echo "No pages locked after fsync"
9975
9976         reset_async
9977         return 0
9978 }
9979 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9980
9981 test_118h() {
9982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9983         remote_ost_nodsh && skip "remote OST with nodsh"
9984
9985         reset_async
9986
9987         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9988         set_nodes_failloc "$(osts_nodes)" 0x20e
9989         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9990         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9991         RC=$?
9992
9993         set_nodes_failloc "$(osts_nodes)" 0
9994         if [[ $RC -eq 0 ]]; then
9995                 error "Must return error due to dropped pages, rc=$RC"
9996         fi
9997
9998         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9999         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10000         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10001                     grep -c writeback)
10002         if [[ $LOCKED -ne 0 ]]; then
10003                 error "Locked pages remain in cache, locked=$LOCKED"
10004         fi
10005
10006         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10007                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10008         fi
10009
10010         rm -f $DIR/$tfile
10011         echo "No pages locked after fsync"
10012
10013         return 0
10014 }
10015 run_test 118h "Verify timeout in handling recoverables errors  =========="
10016
10017 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10018
10019 test_118i() {
10020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10021         remote_ost_nodsh && skip "remote OST with nodsh"
10022
10023         reset_async
10024
10025         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10026         set_nodes_failloc "$(osts_nodes)" 0x20e
10027
10028         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10029         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10030         PID=$!
10031         sleep 5
10032         set_nodes_failloc "$(osts_nodes)" 0
10033
10034         wait $PID
10035         RC=$?
10036         if [[ $RC -ne 0 ]]; then
10037                 error "got error, but should be not, rc=$RC"
10038         fi
10039
10040         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10041         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10042         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10043         if [[ $LOCKED -ne 0 ]]; then
10044                 error "Locked pages remain in cache, locked=$LOCKED"
10045         fi
10046
10047         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10048                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10049         fi
10050
10051         rm -f $DIR/$tfile
10052         echo "No pages locked after fsync"
10053
10054         return 0
10055 }
10056 run_test 118i "Fix error before timeout in recoverable error  =========="
10057
10058 [ "$SLOW" = "no" ] && set_resend_count 4
10059
10060 test_118j() {
10061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10062         remote_ost_nodsh && skip "remote OST with nodsh"
10063
10064         reset_async
10065
10066         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10067         set_nodes_failloc "$(osts_nodes)" 0x220
10068
10069         # return -EIO from OST
10070         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10071         RC=$?
10072         set_nodes_failloc "$(osts_nodes)" 0x0
10073         if [[ $RC -eq 0 ]]; then
10074                 error "Must return error due to dropped pages, rc=$RC"
10075         fi
10076
10077         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10078         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10079         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10080         if [[ $LOCKED -ne 0 ]]; then
10081                 error "Locked pages remain in cache, locked=$LOCKED"
10082         fi
10083
10084         # in recoverable error on OST we want resend and stay until it finished
10085         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10086                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10087         fi
10088
10089         rm -f $DIR/$tfile
10090         echo "No pages locked after fsync"
10091
10092         return 0
10093 }
10094 run_test 118j "Simulate unrecoverable OST side error =========="
10095
10096 test_118k()
10097 {
10098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10099         remote_ost_nodsh && skip "remote OSTs with nodsh"
10100
10101         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10102         set_nodes_failloc "$(osts_nodes)" 0x20e
10103         test_mkdir $DIR/$tdir
10104
10105         for ((i=0;i<10;i++)); do
10106                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10107                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10108                 SLEEPPID=$!
10109                 sleep 0.500s
10110                 kill $SLEEPPID
10111                 wait $SLEEPPID
10112         done
10113
10114         set_nodes_failloc "$(osts_nodes)" 0
10115         rm -rf $DIR/$tdir
10116 }
10117 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10118
10119 test_118l() # LU-646
10120 {
10121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10122
10123         test_mkdir $DIR/$tdir
10124         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10125         rm -rf $DIR/$tdir
10126 }
10127 run_test 118l "fsync dir"
10128
10129 test_118m() # LU-3066
10130 {
10131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10132
10133         test_mkdir $DIR/$tdir
10134         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10135         rm -rf $DIR/$tdir
10136 }
10137 run_test 118m "fdatasync dir ========="
10138
10139 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10140
10141 test_118n()
10142 {
10143         local begin
10144         local end
10145
10146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10147         remote_ost_nodsh && skip "remote OSTs with nodsh"
10148
10149         # Sleep to avoid a cached response.
10150         #define OBD_STATFS_CACHE_SECONDS 1
10151         sleep 2
10152
10153         # Inject a 10 second delay in the OST_STATFS handler.
10154         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10155         set_nodes_failloc "$(osts_nodes)" 0x242
10156
10157         begin=$SECONDS
10158         stat --file-system $MOUNT > /dev/null
10159         end=$SECONDS
10160
10161         set_nodes_failloc "$(osts_nodes)" 0
10162
10163         if ((end - begin > 20)); then
10164             error "statfs took $((end - begin)) seconds, expected 10"
10165         fi
10166 }
10167 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10168
10169 test_119a() # bug 11737
10170 {
10171         BSIZE=$((512 * 1024))
10172         directio write $DIR/$tfile 0 1 $BSIZE
10173         # We ask to read two blocks, which is more than a file size.
10174         # directio will indicate an error when requested and actual
10175         # sizes aren't equeal (a normal situation in this case) and
10176         # print actual read amount.
10177         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10178         if [ "$NOB" != "$BSIZE" ]; then
10179                 error "read $NOB bytes instead of $BSIZE"
10180         fi
10181         rm -f $DIR/$tfile
10182 }
10183 run_test 119a "Short directIO read must return actual read amount"
10184
10185 test_119b() # bug 11737
10186 {
10187         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10188
10189         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10190         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10191         sync
10192         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10193                 error "direct read failed"
10194         rm -f $DIR/$tfile
10195 }
10196 run_test 119b "Sparse directIO read must return actual read amount"
10197
10198 test_119c() # bug 13099
10199 {
10200         BSIZE=1048576
10201         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10202         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10203         rm -f $DIR/$tfile
10204 }
10205 run_test 119c "Testing for direct read hitting hole"
10206
10207 test_119d() # bug 15950
10208 {
10209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10210
10211         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10212         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10213         BSIZE=1048576
10214         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10215         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10216         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10217         lctl set_param fail_loc=0x40d
10218         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10219         pid_dio=$!
10220         sleep 1
10221         cat $DIR/$tfile > /dev/null &
10222         lctl set_param fail_loc=0
10223         pid_reads=$!
10224         wait $pid_dio
10225         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10226         sleep 2
10227         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10228         error "the read rpcs have not completed in 2s"
10229         rm -f $DIR/$tfile
10230         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10231 }
10232 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10233
10234 test_120a() {
10235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10236         remote_mds_nodsh && skip "remote MDS with nodsh"
10237         test_mkdir -i0 -c1 $DIR/$tdir
10238         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10239                 skip_env "no early lock cancel on server"
10240
10241         lru_resize_disable mdc
10242         lru_resize_disable osc
10243         cancel_lru_locks mdc
10244         # asynchronous object destroy at MDT could cause bl ast to client
10245         cancel_lru_locks osc
10246
10247         stat $DIR/$tdir > /dev/null
10248         can1=$(do_facet mds1 \
10249                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10250                awk '/ldlm_cancel/ {print $2}')
10251         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10252                awk '/ldlm_bl_callback/ {print $2}')
10253         test_mkdir -i0 -c1 $DIR/$tdir/d1
10254         can2=$(do_facet mds1 \
10255                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10256                awk '/ldlm_cancel/ {print $2}')
10257         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10258                awk '/ldlm_bl_callback/ {print $2}')
10259         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10260         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10261         lru_resize_enable mdc
10262         lru_resize_enable osc
10263 }
10264 run_test 120a "Early Lock Cancel: mkdir test"
10265
10266 test_120b() {
10267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10268         remote_mds_nodsh && skip "remote MDS with nodsh"
10269         test_mkdir $DIR/$tdir
10270         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10271                 skip_env "no early lock cancel on server"
10272
10273         lru_resize_disable mdc
10274         lru_resize_disable osc
10275         cancel_lru_locks mdc
10276         stat $DIR/$tdir > /dev/null
10277         can1=$(do_facet $SINGLEMDS \
10278                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10279                awk '/ldlm_cancel/ {print $2}')
10280         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10281                awk '/ldlm_bl_callback/ {print $2}')
10282         touch $DIR/$tdir/f1
10283         can2=$(do_facet $SINGLEMDS \
10284                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10285                awk '/ldlm_cancel/ {print $2}')
10286         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10287                awk '/ldlm_bl_callback/ {print $2}')
10288         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10289         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10290         lru_resize_enable mdc
10291         lru_resize_enable osc
10292 }
10293 run_test 120b "Early Lock Cancel: create test"
10294
10295 test_120c() {
10296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10297         remote_mds_nodsh && skip "remote MDS with nodsh"
10298         test_mkdir -i0 -c1 $DIR/$tdir
10299         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10300                 skip "no early lock cancel on server"
10301
10302         lru_resize_disable mdc
10303         lru_resize_disable osc
10304         test_mkdir -i0 -c1 $DIR/$tdir/d1
10305         test_mkdir -i0 -c1 $DIR/$tdir/d2
10306         touch $DIR/$tdir/d1/f1
10307         cancel_lru_locks mdc
10308         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10309         can1=$(do_facet mds1 \
10310                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10311                awk '/ldlm_cancel/ {print $2}')
10312         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10313                awk '/ldlm_bl_callback/ {print $2}')
10314         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10315         can2=$(do_facet mds1 \
10316                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10317                awk '/ldlm_cancel/ {print $2}')
10318         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10319                awk '/ldlm_bl_callback/ {print $2}')
10320         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10321         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10322         lru_resize_enable mdc
10323         lru_resize_enable osc
10324 }
10325 run_test 120c "Early Lock Cancel: link test"
10326
10327 test_120d() {
10328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10329         remote_mds_nodsh && skip "remote MDS with nodsh"
10330         test_mkdir -i0 -c1 $DIR/$tdir
10331         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10332                 skip_env "no early lock cancel on server"
10333
10334         lru_resize_disable mdc
10335         lru_resize_disable osc
10336         touch $DIR/$tdir
10337         cancel_lru_locks mdc
10338         stat $DIR/$tdir > /dev/null
10339         can1=$(do_facet mds1 \
10340                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10341                awk '/ldlm_cancel/ {print $2}')
10342         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10343                awk '/ldlm_bl_callback/ {print $2}')
10344         chmod a+x $DIR/$tdir
10345         can2=$(do_facet mds1 \
10346                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10347                awk '/ldlm_cancel/ {print $2}')
10348         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10349                awk '/ldlm_bl_callback/ {print $2}')
10350         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10351         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10352         lru_resize_enable mdc
10353         lru_resize_enable osc
10354 }
10355 run_test 120d "Early Lock Cancel: setattr test"
10356
10357 test_120e() {
10358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10359         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10360                 skip_env "no early lock cancel on server"
10361         remote_mds_nodsh && skip "remote MDS with nodsh"
10362
10363         local dlmtrace_set=false
10364
10365         test_mkdir -i0 -c1 $DIR/$tdir
10366         lru_resize_disable mdc
10367         lru_resize_disable osc
10368         ! $LCTL get_param debug | grep -q dlmtrace &&
10369                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10370         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10371         cancel_lru_locks mdc
10372         cancel_lru_locks osc
10373         dd if=$DIR/$tdir/f1 of=/dev/null
10374         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10375         # XXX client can not do early lock cancel of OST lock
10376         # during unlink (LU-4206), so cancel osc lock now.
10377         sleep 2
10378         cancel_lru_locks osc
10379         can1=$(do_facet mds1 \
10380                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10381                awk '/ldlm_cancel/ {print $2}')
10382         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10383                awk '/ldlm_bl_callback/ {print $2}')
10384         unlink $DIR/$tdir/f1
10385         sleep 5
10386         can2=$(do_facet mds1 \
10387                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10388                awk '/ldlm_cancel/ {print $2}')
10389         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10390                awk '/ldlm_bl_callback/ {print $2}')
10391         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10392                 $LCTL dk $TMP/cancel.debug.txt
10393         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10394                 $LCTL dk $TMP/blocking.debug.txt
10395         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10396         lru_resize_enable mdc
10397         lru_resize_enable osc
10398 }
10399 run_test 120e "Early Lock Cancel: unlink test"
10400
10401 test_120f() {
10402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10403         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10404                 skip_env "no early lock cancel on server"
10405         remote_mds_nodsh && skip "remote MDS with nodsh"
10406
10407         test_mkdir -i0 -c1 $DIR/$tdir
10408         lru_resize_disable mdc
10409         lru_resize_disable osc
10410         test_mkdir -i0 -c1 $DIR/$tdir/d1
10411         test_mkdir -i0 -c1 $DIR/$tdir/d2
10412         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10413         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10414         cancel_lru_locks mdc
10415         cancel_lru_locks osc
10416         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10417         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10418         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10419         # XXX client can not do early lock cancel of OST lock
10420         # during rename (LU-4206), so cancel osc lock now.
10421         sleep 2
10422         cancel_lru_locks osc
10423         can1=$(do_facet mds1 \
10424                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10425                awk '/ldlm_cancel/ {print $2}')
10426         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10427                awk '/ldlm_bl_callback/ {print $2}')
10428         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10429         sleep 5
10430         can2=$(do_facet mds1 \
10431                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10432                awk '/ldlm_cancel/ {print $2}')
10433         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10434                awk '/ldlm_bl_callback/ {print $2}')
10435         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10436         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10437         lru_resize_enable mdc
10438         lru_resize_enable osc
10439 }
10440 run_test 120f "Early Lock Cancel: rename test"
10441
10442 test_120g() {
10443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10444         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10445                 skip_env "no early lock cancel on server"
10446         remote_mds_nodsh && skip "remote MDS with nodsh"
10447
10448         lru_resize_disable mdc
10449         lru_resize_disable osc
10450         count=10000
10451         echo create $count files
10452         test_mkdir $DIR/$tdir
10453         cancel_lru_locks mdc
10454         cancel_lru_locks osc
10455         t0=$(date +%s)
10456
10457         can0=$(do_facet $SINGLEMDS \
10458                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10459                awk '/ldlm_cancel/ {print $2}')
10460         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10461                awk '/ldlm_bl_callback/ {print $2}')
10462         createmany -o $DIR/$tdir/f $count
10463         sync
10464         can1=$(do_facet $SINGLEMDS \
10465                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10466                awk '/ldlm_cancel/ {print $2}')
10467         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10468                awk '/ldlm_bl_callback/ {print $2}')
10469         t1=$(date +%s)
10470         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10471         echo rm $count files
10472         rm -r $DIR/$tdir
10473         sync
10474         can2=$(do_facet $SINGLEMDS \
10475                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10476                awk '/ldlm_cancel/ {print $2}')
10477         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10478                awk '/ldlm_bl_callback/ {print $2}')
10479         t2=$(date +%s)
10480         echo total: $count removes in $((t2-t1))
10481         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10482         sleep 2
10483         # wait for commitment of removal
10484         lru_resize_enable mdc
10485         lru_resize_enable osc
10486 }
10487 run_test 120g "Early Lock Cancel: performance test"
10488
10489 test_121() { #bug #10589
10490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10491
10492         rm -rf $DIR/$tfile
10493         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10494 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10495         lctl set_param fail_loc=0x310
10496         cancel_lru_locks osc > /dev/null
10497         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10498         lctl set_param fail_loc=0
10499         [[ $reads -eq $writes ]] ||
10500                 error "read $reads blocks, must be $writes blocks"
10501 }
10502 run_test 121 "read cancel race ========="
10503
10504 test_123a() { # was test 123, statahead(bug 11401)
10505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10506
10507         SLOWOK=0
10508         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10509                 log "testing UP system. Performance may be lower than expected."
10510                 SLOWOK=1
10511         fi
10512
10513         rm -rf $DIR/$tdir
10514         test_mkdir $DIR/$tdir
10515         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10516         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10517         MULT=10
10518         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10519                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10520
10521                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10522                 lctl set_param -n llite.*.statahead_max 0
10523                 lctl get_param llite.*.statahead_max
10524                 cancel_lru_locks mdc
10525                 cancel_lru_locks osc
10526                 stime=`date +%s`
10527                 time ls -l $DIR/$tdir | wc -l
10528                 etime=`date +%s`
10529                 delta=$((etime - stime))
10530                 log "ls $i files without statahead: $delta sec"
10531                 lctl set_param llite.*.statahead_max=$max
10532
10533                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10534                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10535                 cancel_lru_locks mdc
10536                 cancel_lru_locks osc
10537                 stime=`date +%s`
10538                 time ls -l $DIR/$tdir | wc -l
10539                 etime=`date +%s`
10540                 delta_sa=$((etime - stime))
10541                 log "ls $i files with statahead: $delta_sa sec"
10542                 lctl get_param -n llite.*.statahead_stats
10543                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10544
10545                 [[ $swrong -lt $ewrong ]] &&
10546                         log "statahead was stopped, maybe too many locks held!"
10547                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10548
10549                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10550                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10551                     lctl set_param -n llite.*.statahead_max 0
10552                     lctl get_param llite.*.statahead_max
10553                     cancel_lru_locks mdc
10554                     cancel_lru_locks osc
10555                     stime=`date +%s`
10556                     time ls -l $DIR/$tdir | wc -l
10557                     etime=`date +%s`
10558                     delta=$((etime - stime))
10559                     log "ls $i files again without statahead: $delta sec"
10560                     lctl set_param llite.*.statahead_max=$max
10561                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10562                         if [  $SLOWOK -eq 0 ]; then
10563                                 error "ls $i files is slower with statahead!"
10564                         else
10565                                 log "ls $i files is slower with statahead!"
10566                         fi
10567                         break
10568                     fi
10569                 fi
10570
10571                 [ $delta -gt 20 ] && break
10572                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10573                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10574         done
10575         log "ls done"
10576
10577         stime=`date +%s`
10578         rm -r $DIR/$tdir
10579         sync
10580         etime=`date +%s`
10581         delta=$((etime - stime))
10582         log "rm -r $DIR/$tdir/: $delta seconds"
10583         log "rm done"
10584         lctl get_param -n llite.*.statahead_stats
10585 }
10586 run_test 123a "verify statahead work"
10587
10588 test_123b () { # statahead(bug 15027)
10589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10590
10591         test_mkdir $DIR/$tdir
10592         createmany -o $DIR/$tdir/$tfile-%d 1000
10593
10594         cancel_lru_locks mdc
10595         cancel_lru_locks osc
10596
10597 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10598         lctl set_param fail_loc=0x80000803
10599         ls -lR $DIR/$tdir > /dev/null
10600         log "ls done"
10601         lctl set_param fail_loc=0x0
10602         lctl get_param -n llite.*.statahead_stats
10603         rm -r $DIR/$tdir
10604         sync
10605
10606 }
10607 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10608
10609 test_124a() {
10610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10611         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10612                 skip_env "no lru resize on server"
10613
10614         local NR=2000
10615
10616         test_mkdir $DIR/$tdir
10617
10618         log "create $NR files at $DIR/$tdir"
10619         createmany -o $DIR/$tdir/f $NR ||
10620                 error "failed to create $NR files in $DIR/$tdir"
10621
10622         cancel_lru_locks mdc
10623         ls -l $DIR/$tdir > /dev/null
10624
10625         local NSDIR=""
10626         local LRU_SIZE=0
10627         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10628                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10629                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10630                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10631                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10632                         log "NSDIR=$NSDIR"
10633                         log "NS=$(basename $NSDIR)"
10634                         break
10635                 fi
10636         done
10637
10638         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10639                 skip "Not enough cached locks created!"
10640         fi
10641         log "LRU=$LRU_SIZE"
10642
10643         local SLEEP=30
10644
10645         # We know that lru resize allows one client to hold $LIMIT locks
10646         # for 10h. After that locks begin to be killed by client.
10647         local MAX_HRS=10
10648         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10649         log "LIMIT=$LIMIT"
10650         if [ $LIMIT -lt $LRU_SIZE ]; then
10651                 skip "Limit is too small $LIMIT"
10652         fi
10653
10654         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10655         # killing locks. Some time was spent for creating locks. This means
10656         # that up to the moment of sleep finish we must have killed some of
10657         # them (10-100 locks). This depends on how fast ther were created.
10658         # Many of them were touched in almost the same moment and thus will
10659         # be killed in groups.
10660         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10661
10662         # Use $LRU_SIZE_B here to take into account real number of locks
10663         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10664         local LRU_SIZE_B=$LRU_SIZE
10665         log "LVF=$LVF"
10666         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10667         log "OLD_LVF=$OLD_LVF"
10668         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10669
10670         # Let's make sure that we really have some margin. Client checks
10671         # cached locks every 10 sec.
10672         SLEEP=$((SLEEP+20))
10673         log "Sleep ${SLEEP} sec"
10674         local SEC=0
10675         while ((SEC<$SLEEP)); do
10676                 echo -n "..."
10677                 sleep 5
10678                 SEC=$((SEC+5))
10679                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10680                 echo -n "$LRU_SIZE"
10681         done
10682         echo ""
10683         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10684         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10685
10686         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10687                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10688                 unlinkmany $DIR/$tdir/f $NR
10689                 return
10690         }
10691
10692         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10693         log "unlink $NR files at $DIR/$tdir"
10694         unlinkmany $DIR/$tdir/f $NR
10695 }
10696 run_test 124a "lru resize ======================================="
10697
10698 get_max_pool_limit()
10699 {
10700         local limit=$($LCTL get_param \
10701                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10702         local max=0
10703         for l in $limit; do
10704                 if [[ $l -gt $max ]]; then
10705                         max=$l
10706                 fi
10707         done
10708         echo $max
10709 }
10710
10711 test_124b() {
10712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10713         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10714                 skip_env "no lru resize on server"
10715
10716         LIMIT=$(get_max_pool_limit)
10717
10718         NR=$(($(default_lru_size)*20))
10719         if [[ $NR -gt $LIMIT ]]; then
10720                 log "Limit lock number by $LIMIT locks"
10721                 NR=$LIMIT
10722         fi
10723
10724         IFree=$(mdsrate_inodes_available)
10725         if [ $IFree -lt $NR ]; then
10726                 log "Limit lock number by $IFree inodes"
10727                 NR=$IFree
10728         fi
10729
10730         lru_resize_disable mdc
10731         test_mkdir -p $DIR/$tdir/disable_lru_resize
10732
10733         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10734         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10735         cancel_lru_locks mdc
10736         stime=`date +%s`
10737         PID=""
10738         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10739         PID="$PID $!"
10740         sleep 2
10741         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10742         PID="$PID $!"
10743         sleep 2
10744         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10745         PID="$PID $!"
10746         wait $PID
10747         etime=`date +%s`
10748         nolruresize_delta=$((etime-stime))
10749         log "ls -la time: $nolruresize_delta seconds"
10750         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10751         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10752
10753         lru_resize_enable mdc
10754         test_mkdir -p $DIR/$tdir/enable_lru_resize
10755
10756         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10757         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10758         cancel_lru_locks mdc
10759         stime=`date +%s`
10760         PID=""
10761         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10762         PID="$PID $!"
10763         sleep 2
10764         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10765         PID="$PID $!"
10766         sleep 2
10767         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10768         PID="$PID $!"
10769         wait $PID
10770         etime=`date +%s`
10771         lruresize_delta=$((etime-stime))
10772         log "ls -la time: $lruresize_delta seconds"
10773         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10774
10775         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10776                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10777         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10778                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10779         else
10780                 log "lru resize performs the same with no lru resize"
10781         fi
10782         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10783 }
10784 run_test 124b "lru resize (performance test) ======================="
10785
10786 test_124c() {
10787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10788         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10789                 skip_env "no lru resize on server"
10790
10791         # cache ununsed locks on client
10792         local nr=100
10793         cancel_lru_locks mdc
10794         test_mkdir $DIR/$tdir
10795         createmany -o $DIR/$tdir/f $nr ||
10796                 error "failed to create $nr files in $DIR/$tdir"
10797         ls -l $DIR/$tdir > /dev/null
10798
10799         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10800         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10801         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10802         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10803         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10804
10805         # set lru_max_age to 1 sec
10806         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10807         echo "sleep $((recalc_p * 2)) seconds..."
10808         sleep $((recalc_p * 2))
10809
10810         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10811         # restore lru_max_age
10812         $LCTL set_param -n $nsdir.lru_max_age $max_age
10813         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10814         unlinkmany $DIR/$tdir/f $nr
10815 }
10816 run_test 124c "LRUR cancel very aged locks"
10817
10818 test_125() { # 13358
10819         $LCTL get_param -n llite.*.client_type | grep -q local ||
10820                 skip "must run as local client"
10821         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10822                 skip_env "must have acl enabled"
10823         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10824
10825         test_mkdir $DIR/$tdir
10826         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10827         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10828         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10829 }
10830 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10831
10832 test_126() { # bug 12829/13455
10833         $GSS && skip_env "must run as gss disabled"
10834         $LCTL get_param -n llite.*.client_type | grep -q local ||
10835                 skip "must run as local client"
10836         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10837
10838         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10839         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10840         rm -f $DIR/$tfile
10841         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10842 }
10843 run_test 126 "check that the fsgid provided by the client is taken into account"
10844
10845 test_127a() { # bug 15521
10846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10847
10848         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10849         $LCTL set_param osc.*.stats=0
10850         FSIZE=$((2048 * 1024))
10851         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10852         cancel_lru_locks osc
10853         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10854
10855         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10856         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10857                 echo "got $COUNT $NAME"
10858                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10859                 eval $NAME=$COUNT || error "Wrong proc format"
10860
10861                 case $NAME in
10862                         read_bytes|write_bytes)
10863                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10864                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10865                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10866                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10867                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10868                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10869                                 error "sumsquare is too small: $SUMSQ"
10870                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10871                                 error "sumsquare is too big: $SUMSQ"
10872                         ;;
10873                         *) ;;
10874                 esac
10875         done < $DIR/${tfile}.tmp
10876
10877         #check that we actually got some stats
10878         [ "$read_bytes" ] || error "Missing read_bytes stats"
10879         [ "$write_bytes" ] || error "Missing write_bytes stats"
10880         [ "$read_bytes" != 0 ] || error "no read done"
10881         [ "$write_bytes" != 0 ] || error "no write done"
10882 }
10883 run_test 127a "verify the client stats are sane"
10884
10885 test_127b() { # bug LU-333
10886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10887         local name count samp unit min max sum sumsq
10888
10889         $LCTL set_param llite.*.stats=0
10890
10891         # perform 2 reads and writes so MAX is different from SUM.
10892         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10893         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10894         cancel_lru_locks osc
10895         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10896         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10897
10898         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10899         while read name count samp unit min max sum sumsq; do
10900                 echo "got $count $name"
10901                 eval $name=$count || error "Wrong proc format"
10902
10903                 case $name in
10904                 read_bytes)
10905                         [ $count -ne 2 ] && error "count is not 2: $count"
10906                         [ $min -ne $PAGE_SIZE ] &&
10907                                 error "min is not $PAGE_SIZE: $min"
10908                         [ $max -ne $PAGE_SIZE ] &&
10909                                 error "max is incorrect: $max"
10910                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10911                                 error "sum is wrong: $sum"
10912                         ;;
10913                 write_bytes)
10914                         [ $count -ne 2 ] && error "count is not 2: $count"
10915                         [ $min -ne $PAGE_SIZE ] &&
10916                                 error "min is not $PAGE_SIZE: $min"
10917                         [ $max -ne $PAGE_SIZE ] &&
10918                                 error "max is incorrect: $max"
10919                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10920                                 error "sum is wrong: $sum"
10921                         ;;
10922                 *) ;;
10923                 esac
10924         done < $TMP/$tfile.tmp
10925
10926         #check that we actually got some stats
10927         [ "$read_bytes" ] || error "Missing read_bytes stats"
10928         [ "$write_bytes" ] || error "Missing write_bytes stats"
10929         [ "$read_bytes" != 0 ] || error "no read done"
10930         [ "$write_bytes" != 0 ] || error "no write done"
10931
10932         rm -f $TMP/${tfile}.tmp
10933 }
10934 run_test 127b "verify the llite client stats are sane"
10935
10936 test_128() { # bug 15212
10937         touch $DIR/$tfile
10938         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10939                 find $DIR/$tfile
10940                 find $DIR/$tfile
10941         EOF
10942
10943         result=$(grep error $TMP/$tfile.log)
10944         rm -f $DIR/$tfile $TMP/$tfile.log
10945         [ -z "$result" ] ||
10946                 error "consecutive find's under interactive lfs failed"
10947 }
10948 run_test 128 "interactive lfs for 2 consecutive find's"
10949
10950 set_dir_limits () {
10951         local mntdev
10952         local canondev
10953         local node
10954
10955         local ldproc=/proc/fs/ldiskfs
10956         local facets=$(get_facets MDS)
10957
10958         for facet in ${facets//,/ }; do
10959                 canondev=$(ldiskfs_canon \
10960                            *.$(convert_facet2label $facet).mntdev $facet)
10961                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10962                         ldproc=/sys/fs/ldiskfs
10963                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10964                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10965         done
10966 }
10967
10968 check_mds_dmesg() {
10969         local facets=$(get_facets MDS)
10970         for facet in ${facets//,/ }; do
10971                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10972         done
10973         return 1
10974 }
10975
10976 test_129() {
10977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10978         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10979                 skip "Need MDS version with at least 2.5.56"
10980         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10981                 skip_env "ldiskfs only test"
10982         fi
10983         remote_mds_nodsh && skip "remote MDS with nodsh"
10984
10985         local ENOSPC=28
10986         local EFBIG=27
10987         local has_warning=false
10988
10989         rm -rf $DIR/$tdir
10990         mkdir -p $DIR/$tdir
10991
10992         # block size of mds1
10993         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
10994         set_dir_limits $maxsize $maxsize
10995         local dirsize=$(stat -c%s "$DIR/$tdir")
10996         local nfiles=0
10997         while [[ $dirsize -le $maxsize ]]; do
10998                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
10999                 rc=$?
11000                 if ! $has_warning; then
11001                         check_mds_dmesg '"is approaching"' && has_warning=true
11002                 fi
11003                 # check two errors:
11004                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11005                 # EFBIG for previous versions included in ldiskfs series
11006                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11007                         set_dir_limits 0 0
11008                         echo "return code $rc received as expected"
11009
11010                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11011                                 error_exit "create failed w/o dir size limit"
11012
11013                         check_mds_dmesg '"has reached"' ||
11014                                 error_exit "reached message should be output"
11015
11016                         [ $has_warning = "false" ] &&
11017                                 error_exit "warning message should be output"
11018
11019                         dirsize=$(stat -c%s "$DIR/$tdir")
11020
11021                         [[ $dirsize -ge $maxsize ]] && return 0
11022                         error_exit "current dir size $dirsize, " \
11023                                    "previous limit $maxsize"
11024                 elif [ $rc -ne 0 ]; then
11025                         set_dir_limits 0 0
11026                         error_exit "return $rc received instead of expected " \
11027                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11028                 fi
11029                 nfiles=$((nfiles + 1))
11030                 dirsize=$(stat -c%s "$DIR/$tdir")
11031         done
11032
11033         set_dir_limits 0 0
11034         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11035 }
11036 run_test 129 "test directory size limit ========================"
11037
11038 OLDIFS="$IFS"
11039 cleanup_130() {
11040         trap 0
11041         IFS="$OLDIFS"
11042 }
11043
11044 test_130a() {
11045         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11046         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11047
11048         trap cleanup_130 EXIT RETURN
11049
11050         local fm_file=$DIR/$tfile
11051         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11052         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11053                 error "dd failed for $fm_file"
11054
11055         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11056         filefrag -ves $fm_file
11057         RC=$?
11058         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11059                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11060         [ $RC != 0 ] && error "filefrag $fm_file failed"
11061
11062         filefrag_op=$(filefrag -ve -k $fm_file |
11063                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11064         lun=$($LFS getstripe -i $fm_file)
11065
11066         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11067         IFS=$'\n'
11068         tot_len=0
11069         for line in $filefrag_op
11070         do
11071                 frag_lun=`echo $line | cut -d: -f5`
11072                 ext_len=`echo $line | cut -d: -f4`
11073                 if (( $frag_lun != $lun )); then
11074                         cleanup_130
11075                         error "FIEMAP on 1-stripe file($fm_file) failed"
11076                         return
11077                 fi
11078                 (( tot_len += ext_len ))
11079         done
11080
11081         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11082                 cleanup_130
11083                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11084                 return
11085         fi
11086
11087         cleanup_130
11088
11089         echo "FIEMAP on single striped file succeeded"
11090 }
11091 run_test 130a "FIEMAP (1-stripe file)"
11092
11093 test_130b() {
11094         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11095
11096         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11097         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11098
11099         trap cleanup_130 EXIT RETURN
11100
11101         local fm_file=$DIR/$tfile
11102         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11103                         error "setstripe on $fm_file"
11104         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11105                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11106
11107         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11108                 error "dd failed on $fm_file"
11109
11110         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11111         filefrag_op=$(filefrag -ve -k $fm_file |
11112                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11113
11114         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11115                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11116
11117         IFS=$'\n'
11118         tot_len=0
11119         num_luns=1
11120         for line in $filefrag_op
11121         do
11122                 frag_lun=$(echo $line | cut -d: -f5 |
11123                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11124                 ext_len=$(echo $line | cut -d: -f4)
11125                 if (( $frag_lun != $last_lun )); then
11126                         if (( tot_len != 1024 )); then
11127                                 cleanup_130
11128                                 error "FIEMAP on $fm_file failed; returned " \
11129                                 "len $tot_len for OST $last_lun instead of 1024"
11130                                 return
11131                         else
11132                                 (( num_luns += 1 ))
11133                                 tot_len=0
11134                         fi
11135                 fi
11136                 (( tot_len += ext_len ))
11137                 last_lun=$frag_lun
11138         done
11139         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11140                 cleanup_130
11141                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11142                         "luns or wrong len for OST $last_lun"
11143                 return
11144         fi
11145
11146         cleanup_130
11147
11148         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11149 }
11150 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11151
11152 test_130c() {
11153         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11154
11155         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11156         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11157
11158         trap cleanup_130 EXIT RETURN
11159
11160         local fm_file=$DIR/$tfile
11161         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11162         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11163                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11164
11165         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11166                         error "dd failed on $fm_file"
11167
11168         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11169         filefrag_op=$(filefrag -ve -k $fm_file |
11170                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11171
11172         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11173                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11174
11175         IFS=$'\n'
11176         tot_len=0
11177         num_luns=1
11178         for line in $filefrag_op
11179         do
11180                 frag_lun=$(echo $line | cut -d: -f5 |
11181                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11182                 ext_len=$(echo $line | cut -d: -f4)
11183                 if (( $frag_lun != $last_lun )); then
11184                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11185                         if (( logical != 512 )); then
11186                                 cleanup_130
11187                                 error "FIEMAP on $fm_file failed; returned " \
11188                                 "logical start for lun $logical instead of 512"
11189                                 return
11190                         fi
11191                         if (( tot_len != 512 )); then
11192                                 cleanup_130
11193                                 error "FIEMAP on $fm_file failed; returned " \
11194                                 "len $tot_len for OST $last_lun instead of 1024"
11195                                 return
11196                         else
11197                                 (( num_luns += 1 ))
11198                                 tot_len=0
11199                         fi
11200                 fi
11201                 (( tot_len += ext_len ))
11202                 last_lun=$frag_lun
11203         done
11204         if (( num_luns != 2 || tot_len != 512 )); then
11205                 cleanup_130
11206                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11207                         "luns or wrong len for OST $last_lun"
11208                 return
11209         fi
11210
11211         cleanup_130
11212
11213         echo "FIEMAP on 2-stripe file with hole succeeded"
11214 }
11215 run_test 130c "FIEMAP (2-stripe file with hole)"
11216
11217 test_130d() {
11218         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11219
11220         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11221         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11222
11223         trap cleanup_130 EXIT RETURN
11224
11225         local fm_file=$DIR/$tfile
11226         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11227                         error "setstripe on $fm_file"
11228         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11229                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11230
11231         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11232         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11233                 error "dd failed on $fm_file"
11234
11235         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11236         filefrag_op=$(filefrag -ve -k $fm_file |
11237                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11238
11239         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11240                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11241
11242         IFS=$'\n'
11243         tot_len=0
11244         num_luns=1
11245         for line in $filefrag_op
11246         do
11247                 frag_lun=$(echo $line | cut -d: -f5 |
11248                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11249                 ext_len=$(echo $line | cut -d: -f4)
11250                 if (( $frag_lun != $last_lun )); then
11251                         if (( tot_len != 1024 )); then
11252                                 cleanup_130
11253                                 error "FIEMAP on $fm_file failed; returned " \
11254                                 "len $tot_len for OST $last_lun instead of 1024"
11255                                 return
11256                         else
11257                                 (( num_luns += 1 ))
11258                                 tot_len=0
11259                         fi
11260                 fi
11261                 (( tot_len += ext_len ))
11262                 last_lun=$frag_lun
11263         done
11264         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11265                 cleanup_130
11266                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11267                         "luns or wrong len for OST $last_lun"
11268                 return
11269         fi
11270
11271         cleanup_130
11272
11273         echo "FIEMAP on N-stripe file succeeded"
11274 }
11275 run_test 130d "FIEMAP (N-stripe file)"
11276
11277 test_130e() {
11278         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11279
11280         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11281         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11282
11283         trap cleanup_130 EXIT RETURN
11284
11285         local fm_file=$DIR/$tfile
11286         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11287         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11288                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11289
11290         NUM_BLKS=512
11291         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11292         for ((i = 0; i < $NUM_BLKS; i++))
11293         do
11294                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11295         done
11296
11297         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11298         filefrag_op=$(filefrag -ve -k $fm_file |
11299                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11300
11301         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11302                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11303
11304         IFS=$'\n'
11305         tot_len=0
11306         num_luns=1
11307         for line in $filefrag_op
11308         do
11309                 frag_lun=$(echo $line | cut -d: -f5 |
11310                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11311                 ext_len=$(echo $line | cut -d: -f4)
11312                 if (( $frag_lun != $last_lun )); then
11313                         if (( tot_len != $EXPECTED_LEN )); then
11314                                 cleanup_130
11315                                 error "FIEMAP on $fm_file failed; returned " \
11316                                 "len $tot_len for OST $last_lun instead " \
11317                                 "of $EXPECTED_LEN"
11318                                 return
11319                         else
11320                                 (( num_luns += 1 ))
11321                                 tot_len=0
11322                         fi
11323                 fi
11324                 (( tot_len += ext_len ))
11325                 last_lun=$frag_lun
11326         done
11327         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11328                 cleanup_130
11329                 error "FIEMAP on $fm_file failed; returned wrong number " \
11330                         "of luns or wrong len for OST $last_lun"
11331                 return
11332         fi
11333
11334         cleanup_130
11335
11336         echo "FIEMAP with continuation calls succeeded"
11337 }
11338 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11339
11340 test_130f() {
11341         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11342         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11343
11344         local fm_file=$DIR/$tfile
11345         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
11346                 error "multiop create with lov_delay_create on $fm_file"
11347
11348         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11349         filefrag_extents=$(filefrag -vek $fm_file |
11350                            awk '/extents? found/ { print $2 }')
11351         if [[ "$filefrag_extents" != "0" ]]; then
11352                 error "FIEMAP on $fm_file failed; " \
11353                       "returned $filefrag_extents expected 0"
11354         fi
11355
11356         rm -f $fm_file
11357 }
11358 run_test 130f "FIEMAP (unstriped file)"
11359
11360 # Test for writev/readv
11361 test_131a() {
11362         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
11363                 error "writev test failed"
11364         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
11365                 error "readv failed"
11366         rm -f $DIR/$tfile
11367 }
11368 run_test 131a "test iov's crossing stripe boundary for writev/readv"
11369
11370 test_131b() {
11371         local fsize=$((524288 + 1048576 + 1572864))
11372         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
11373                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11374                         error "append writev test failed"
11375
11376         ((fsize += 1572864 + 1048576))
11377         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
11378                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11379                         error "append writev test failed"
11380         rm -f $DIR/$tfile
11381 }
11382 run_test 131b "test append writev"
11383
11384 test_131c() {
11385         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
11386         error "NOT PASS"
11387 }
11388 run_test 131c "test read/write on file w/o objects"
11389
11390 test_131d() {
11391         rwv -f $DIR/$tfile -w -n 1 1572864
11392         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
11393         if [ "$NOB" != 1572864 ]; then
11394                 error "Short read filed: read $NOB bytes instead of 1572864"
11395         fi
11396         rm -f $DIR/$tfile
11397 }
11398 run_test 131d "test short read"
11399
11400 test_131e() {
11401         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
11402         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
11403         error "read hitting hole failed"
11404         rm -f $DIR/$tfile
11405 }
11406 run_test 131e "test read hitting hole"
11407
11408 check_stats() {
11409         local facet=$1
11410         local op=$2
11411         local want=${3:-0}
11412         local res
11413
11414         case $facet in
11415         mds*) res=$(do_facet $facet \
11416                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
11417                  ;;
11418         ost*) res=$(do_facet $facet \
11419                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
11420                  ;;
11421         *) error "Wrong facet '$facet'" ;;
11422         esac
11423         [ "$res" ] || error "The counter for $op on $facet was not incremented"
11424         # if the argument $3 is zero, it means any stat increment is ok.
11425         if [[ $want -gt 0 ]]; then
11426                 local count=$(echo $res | awk '{ print $2 }')
11427                 [[ $count -ne $want ]] &&
11428                         error "The $op counter on $facet is $count, not $want"
11429         fi
11430 }
11431
11432 test_133a() {
11433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11434         remote_ost_nodsh && skip "remote OST with nodsh"
11435         remote_mds_nodsh && skip "remote MDS with nodsh"
11436         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11437                 skip_env "MDS doesn't support rename stats"
11438
11439         local testdir=$DIR/${tdir}/stats_testdir
11440
11441         mkdir -p $DIR/${tdir}
11442
11443         # clear stats.
11444         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11445         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11446
11447         # verify mdt stats first.
11448         mkdir ${testdir} || error "mkdir failed"
11449         check_stats $SINGLEMDS "mkdir" 1
11450         touch ${testdir}/${tfile} || error "touch failed"
11451         check_stats $SINGLEMDS "open" 1
11452         check_stats $SINGLEMDS "close" 1
11453         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11454                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11455                 check_stats $SINGLEMDS "mknod" 2
11456         }
11457         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11458         check_stats $SINGLEMDS "unlink" 1
11459         rm -f ${testdir}/${tfile} || error "file remove failed"
11460         check_stats $SINGLEMDS "unlink" 2
11461
11462         # remove working dir and check mdt stats again.
11463         rmdir ${testdir} || error "rmdir failed"
11464         check_stats $SINGLEMDS "rmdir" 1
11465
11466         local testdir1=$DIR/${tdir}/stats_testdir1
11467         mkdir -p ${testdir}
11468         mkdir -p ${testdir1}
11469         touch ${testdir1}/test1
11470         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11471         check_stats $SINGLEMDS "crossdir_rename" 1
11472
11473         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11474         check_stats $SINGLEMDS "samedir_rename" 1
11475
11476         rm -rf $DIR/${tdir}
11477 }
11478 run_test 133a "Verifying MDT stats ========================================"
11479
11480 test_133b() {
11481         local res
11482
11483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11484         remote_ost_nodsh && skip "remote OST with nodsh"
11485         remote_mds_nodsh && skip "remote MDS with nodsh"
11486
11487         local testdir=$DIR/${tdir}/stats_testdir
11488
11489         mkdir -p ${testdir} || error "mkdir failed"
11490         touch ${testdir}/${tfile} || error "touch failed"
11491         cancel_lru_locks mdc
11492
11493         # clear stats.
11494         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11495         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11496
11497         # extra mdt stats verification.
11498         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11499         check_stats $SINGLEMDS "setattr" 1
11500         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11501         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11502         then            # LU-1740
11503                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11504                 check_stats $SINGLEMDS "getattr" 1
11505         fi
11506         rm -rf $DIR/${tdir}
11507
11508         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11509         # so the check below is not reliable
11510         [ $MDSCOUNT -eq 1 ] || return 0
11511
11512         # Sleep to avoid a cached response.
11513         #define OBD_STATFS_CACHE_SECONDS 1
11514         sleep 2
11515         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11516         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11517         $LFS df || error "lfs failed"
11518         check_stats $SINGLEMDS "statfs" 1
11519
11520         # check aggregated statfs (LU-10018)
11521         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11522                 return 0
11523         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11524                 return 0
11525         sleep 2
11526         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11527         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11528         df $DIR
11529         check_stats $SINGLEMDS "statfs" 1
11530
11531         # We want to check that the client didn't send OST_STATFS to
11532         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11533         # extra care is needed here.
11534         if remote_mds; then
11535                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11536                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11537
11538                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11539                 [ "$res" ] && error "OST got STATFS"
11540         fi
11541
11542         return 0
11543 }
11544 run_test 133b "Verifying extra MDT stats =================================="
11545
11546 test_133c() {
11547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11548         remote_ost_nodsh && skip "remote OST with nodsh"
11549         remote_mds_nodsh && skip "remote MDS with nodsh"
11550
11551         local testdir=$DIR/$tdir/stats_testdir
11552
11553         test_mkdir -p $testdir
11554
11555         # verify obdfilter stats.
11556         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11557         sync
11558         cancel_lru_locks osc
11559         wait_delete_completed
11560
11561         # clear stats.
11562         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11563         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11564
11565         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11566                 error "dd failed"
11567         sync
11568         cancel_lru_locks osc
11569         check_stats ost1 "write" 1
11570
11571         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11572         check_stats ost1 "read" 1
11573
11574         > $testdir/$tfile || error "truncate failed"
11575         check_stats ost1 "punch" 1
11576
11577         rm -f $testdir/$tfile || error "file remove failed"
11578         wait_delete_completed
11579         check_stats ost1 "destroy" 1
11580
11581         rm -rf $DIR/$tdir
11582 }
11583 run_test 133c "Verifying OST stats ========================================"
11584
11585 order_2() {
11586         local value=$1
11587         local orig=$value
11588         local order=1
11589
11590         while [ $value -ge 2 ]; do
11591                 order=$((order*2))
11592                 value=$((value/2))
11593         done
11594
11595         if [ $orig -gt $order ]; then
11596                 order=$((order*2))
11597         fi
11598         echo $order
11599 }
11600
11601 size_in_KMGT() {
11602     local value=$1
11603     local size=('K' 'M' 'G' 'T');
11604     local i=0
11605     local size_string=$value
11606
11607     while [ $value -ge 1024 ]; do
11608         if [ $i -gt 3 ]; then
11609             #T is the biggest unit we get here, if that is bigger,
11610             #just return XXXT
11611             size_string=${value}T
11612             break
11613         fi
11614         value=$((value >> 10))
11615         if [ $value -lt 1024 ]; then
11616             size_string=${value}${size[$i]}
11617             break
11618         fi
11619         i=$((i + 1))
11620     done
11621
11622     echo $size_string
11623 }
11624
11625 get_rename_size() {
11626         local size=$1
11627         local context=${2:-.}
11628         local sample=$(do_facet $SINGLEMDS $LCTL \
11629                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11630                 grep -A1 $context |
11631                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11632         echo $sample
11633 }
11634
11635 test_133d() {
11636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11637         remote_ost_nodsh && skip "remote OST with nodsh"
11638         remote_mds_nodsh && skip "remote MDS with nodsh"
11639         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11640                 skip_env "MDS doesn't support rename stats"
11641
11642         local testdir1=$DIR/${tdir}/stats_testdir1
11643         local testdir2=$DIR/${tdir}/stats_testdir2
11644         mkdir -p $DIR/${tdir}
11645
11646         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11647
11648         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11649         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11650
11651         createmany -o $testdir1/test 512 || error "createmany failed"
11652
11653         # check samedir rename size
11654         mv ${testdir1}/test0 ${testdir1}/test_0
11655
11656         local testdir1_size=$(ls -l $DIR/${tdir} |
11657                 awk '/stats_testdir1/ {print $5}')
11658         local testdir2_size=$(ls -l $DIR/${tdir} |
11659                 awk '/stats_testdir2/ {print $5}')
11660
11661         testdir1_size=$(order_2 $testdir1_size)
11662         testdir2_size=$(order_2 $testdir2_size)
11663
11664         testdir1_size=$(size_in_KMGT $testdir1_size)
11665         testdir2_size=$(size_in_KMGT $testdir2_size)
11666
11667         echo "source rename dir size: ${testdir1_size}"
11668         echo "target rename dir size: ${testdir2_size}"
11669
11670         local cmd="do_facet $SINGLEMDS $LCTL "
11671         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11672
11673         eval $cmd || error "$cmd failed"
11674         local samedir=$($cmd | grep 'same_dir')
11675         local same_sample=$(get_rename_size $testdir1_size)
11676         [ -z "$samedir" ] && error "samedir_rename_size count error"
11677         [[ $same_sample -eq 1 ]] ||
11678                 error "samedir_rename_size error $same_sample"
11679         echo "Check same dir rename stats success"
11680
11681         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11682
11683         # check crossdir rename size
11684         mv ${testdir1}/test_0 ${testdir2}/test_0
11685
11686         testdir1_size=$(ls -l $DIR/${tdir} |
11687                 awk '/stats_testdir1/ {print $5}')
11688         testdir2_size=$(ls -l $DIR/${tdir} |
11689                 awk '/stats_testdir2/ {print $5}')
11690
11691         testdir1_size=$(order_2 $testdir1_size)
11692         testdir2_size=$(order_2 $testdir2_size)
11693
11694         testdir1_size=$(size_in_KMGT $testdir1_size)
11695         testdir2_size=$(size_in_KMGT $testdir2_size)
11696
11697         echo "source rename dir size: ${testdir1_size}"
11698         echo "target rename dir size: ${testdir2_size}"
11699
11700         eval $cmd || error "$cmd failed"
11701         local crossdir=$($cmd | grep 'crossdir')
11702         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11703         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11704         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11705         [[ $src_sample -eq 1 ]] ||
11706                 error "crossdir_rename_size error $src_sample"
11707         [[ $tgt_sample -eq 1 ]] ||
11708                 error "crossdir_rename_size error $tgt_sample"
11709         echo "Check cross dir rename stats success"
11710         rm -rf $DIR/${tdir}
11711 }
11712 run_test 133d "Verifying rename_stats ========================================"
11713
11714 test_133e() {
11715         remote_mds_nodsh && skip "remote MDS with nodsh"
11716         remote_ost_nodsh && skip "remote OST with nodsh"
11717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11718
11719         local testdir=$DIR/${tdir}/stats_testdir
11720         local ctr f0 f1 bs=32768 count=42 sum
11721
11722         mkdir -p ${testdir} || error "mkdir failed"
11723
11724         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11725
11726         for ctr in {write,read}_bytes; do
11727                 sync
11728                 cancel_lru_locks osc
11729
11730                 do_facet ost1 $LCTL set_param -n \
11731                         "obdfilter.*.exports.clear=clear"
11732
11733                 if [ $ctr = write_bytes ]; then
11734                         f0=/dev/zero
11735                         f1=${testdir}/${tfile}
11736                 else
11737                         f0=${testdir}/${tfile}
11738                         f1=/dev/null
11739                 fi
11740
11741                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11742                         error "dd failed"
11743                 sync
11744                 cancel_lru_locks osc
11745
11746                 sum=$(do_facet ost1 $LCTL get_param \
11747                         "obdfilter.*.exports.*.stats" |
11748                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11749                                 $1 == ctr { sum += $7 }
11750                                 END { printf("%0.0f", sum) }')
11751
11752                 if ((sum != bs * count)); then
11753                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11754                 fi
11755         done
11756
11757         rm -rf $DIR/${tdir}
11758 }
11759 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11760
11761 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11762
11763 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11764 # not honor the -ignore_readdir_race option correctly. So we call
11765 # error_ignore() rather than error() in these cases. See LU-11152.
11766 error_133() {
11767         if (find --version; do_facet mds1 find --version) |
11768                 grep -q '\b4\.5\.1[1-4]\b'; then
11769                 error_ignore LU-11152 "$@"
11770         else
11771                 error "$@"
11772         fi
11773 }
11774
11775 test_133f() {
11776         # First without trusting modes.
11777         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11778         echo "proc_dirs='$proc_dirs'"
11779         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11780         find $proc_dirs -exec cat '{}' \; &> /dev/null
11781
11782         # Second verifying readability.
11783         $LCTL get_param -R '*' &> /dev/null
11784
11785         # Verifing writability with badarea_io.
11786         find $proc_dirs \
11787                 -ignore_readdir_race \
11788                 -type f \
11789                 -not -name force_lbug \
11790                 -not -name changelog_mask \
11791                 -exec badarea_io '{}' \; ||
11792                         error_133 "find $proc_dirs failed"
11793 }
11794 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11795
11796 test_133g() {
11797         remote_mds_nodsh && skip "remote MDS with nodsh"
11798         remote_ost_nodsh && skip "remote OST with nodsh"
11799
11800         # eventually, this can also be replaced with "lctl get_param -R",
11801         # but not until that option is always available on the server
11802         local facet
11803         for facet in mds1 ost1; do
11804                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11805                         skip_noexit "Too old lustre on $facet"
11806                 local facet_proc_dirs=$(do_facet $facet \
11807                                         \\\ls -d $proc_regexp 2>/dev/null)
11808                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11809                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11810                 do_facet $facet find $facet_proc_dirs \
11811                         ! -name req_history \
11812                         -exec cat '{}' \\\; &> /dev/null
11813
11814                 do_facet $facet find $facet_proc_dirs \
11815                         ! -name req_history \
11816                         -type f \
11817                         -exec cat '{}' \\\; &> /dev/null ||
11818                                 error "proc file read failed"
11819
11820                 do_facet $facet find $facet_proc_dirs \
11821                         -ignore_readdir_race \
11822                         -type f \
11823                         -not -name force_lbug \
11824                         -not -name changelog_mask \
11825                         -exec badarea_io '{}' \\\; ||
11826                                 error_133 "$facet find $facet_proc_dirs failed"
11827         done
11828
11829         # remount the FS in case writes/reads /proc break the FS
11830         cleanup || error "failed to unmount"
11831         setup || error "failed to setup"
11832         true
11833 }
11834 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11835
11836 test_133h() {
11837         remote_mds_nodsh && skip "remote MDS with nodsh"
11838         remote_ost_nodsh && skip "remote OST with nodsh"
11839         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11840                 skip "Need MDS version at least 2.9.54"
11841
11842         local facet
11843
11844         for facet in client mds1 ost1; do
11845                 local facet_proc_dirs=$(do_facet $facet \
11846                                         \\\ls -d $proc_regexp 2> /dev/null)
11847                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11848                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11849                 # Get the list of files that are missing the terminating newline
11850                 local missing=($(do_facet $facet \
11851                         find ${facet_proc_dirs} -type f \|              \
11852                                 while read F\; do                       \
11853                                         awk -v FS='\v' -v RS='\v\v'     \
11854                                         "'END { if(NR>0 &&              \
11855                                         \\\$NF !~ /.*\\\n\$/)           \
11856                                                 print FILENAME}'"       \
11857                                         '\$F'\;                         \
11858                                 done 2>/dev/null))
11859                 [ ${#missing[*]} -eq 0 ] ||
11860                         error "files do not end with newline: ${missing[*]}"
11861         done
11862 }
11863 run_test 133h "Proc files should end with newlines"
11864
11865 test_134a() {
11866         remote_mds_nodsh && skip "remote MDS with nodsh"
11867         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11868                 skip "Need MDS version at least 2.7.54"
11869
11870         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11871         cancel_lru_locks mdc
11872
11873         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11874         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11875         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11876
11877         local nr=1000
11878         createmany -o $DIR/$tdir/f $nr ||
11879                 error "failed to create $nr files in $DIR/$tdir"
11880         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11881
11882         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11883         do_facet mds1 $LCTL set_param fail_loc=0x327
11884         do_facet mds1 $LCTL set_param fail_val=500
11885         touch $DIR/$tdir/m
11886
11887         echo "sleep 10 seconds ..."
11888         sleep 10
11889         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11890
11891         do_facet mds1 $LCTL set_param fail_loc=0
11892         do_facet mds1 $LCTL set_param fail_val=0
11893         [ $lck_cnt -lt $unused ] ||
11894                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11895
11896         rm $DIR/$tdir/m
11897         unlinkmany $DIR/$tdir/f $nr
11898 }
11899 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11900
11901 test_134b() {
11902         remote_mds_nodsh && skip "remote MDS with nodsh"
11903         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11904                 skip "Need MDS version at least 2.7.54"
11905
11906         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11907         cancel_lru_locks mdc
11908
11909         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11910                         ldlm.lock_reclaim_threshold_mb)
11911         # disable reclaim temporarily
11912         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11913
11914         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11915         do_facet mds1 $LCTL set_param fail_loc=0x328
11916         do_facet mds1 $LCTL set_param fail_val=500
11917
11918         $LCTL set_param debug=+trace
11919
11920         local nr=600
11921         createmany -o $DIR/$tdir/f $nr &
11922         local create_pid=$!
11923
11924         echo "Sleep $TIMEOUT seconds ..."
11925         sleep $TIMEOUT
11926         if ! ps -p $create_pid  > /dev/null 2>&1; then
11927                 do_facet mds1 $LCTL set_param fail_loc=0
11928                 do_facet mds1 $LCTL set_param fail_val=0
11929                 do_facet mds1 $LCTL set_param \
11930                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11931                 error "createmany finished incorrectly!"
11932         fi
11933         do_facet mds1 $LCTL set_param fail_loc=0
11934         do_facet mds1 $LCTL set_param fail_val=0
11935         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11936         wait $create_pid || return 1
11937
11938         unlinkmany $DIR/$tdir/f $nr
11939 }
11940 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11941
11942 test_140() { #bug-17379
11943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11944
11945         test_mkdir $DIR/$tdir
11946         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11947         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11948
11949         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11950         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11951         local i=0
11952         while i=$((i + 1)); do
11953                 test_mkdir $i
11954                 cd $i || error "Changing to $i"
11955                 ln -s ../stat stat || error "Creating stat symlink"
11956                 # Read the symlink until ELOOP present,
11957                 # not LBUGing the system is considered success,
11958                 # we didn't overrun the stack.
11959                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11960                 if [ $ret -ne 0 ]; then
11961                         if [ $ret -eq 40 ]; then
11962                                 break  # -ELOOP
11963                         else
11964                                 error "Open stat symlink"
11965                                         return
11966                         fi
11967                 fi
11968         done
11969         i=$((i - 1))
11970         echo "The symlink depth = $i"
11971         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
11972                 error "Invalid symlink depth"
11973
11974         # Test recursive symlink
11975         ln -s symlink_self symlink_self
11976         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11977         echo "open symlink_self returns $ret"
11978         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11979 }
11980 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11981
11982 test_150() {
11983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11984
11985         local TF="$TMP/$tfile"
11986
11987         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11988         cp $TF $DIR/$tfile
11989         cancel_lru_locks $OSC
11990         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
11991         remount_client $MOUNT
11992         df -P $MOUNT
11993         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
11994
11995         $TRUNCATE $TF 6000
11996         $TRUNCATE $DIR/$tfile 6000
11997         cancel_lru_locks $OSC
11998         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
11999
12000         echo "12345" >>$TF
12001         echo "12345" >>$DIR/$tfile
12002         cancel_lru_locks $OSC
12003         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12004
12005         echo "12345" >>$TF
12006         echo "12345" >>$DIR/$tfile
12007         cancel_lru_locks $OSC
12008         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12009
12010         rm -f $TF
12011         true
12012 }
12013 run_test 150 "truncate/append tests"
12014
12015 #LU-2902 roc_hit was not able to read all values from lproc
12016 function roc_hit_init() {
12017         local list=$(comma_list $(osts_nodes))
12018         local dir=$DIR/$tdir-check
12019         local file=$dir/$tfile
12020         local BEFORE
12021         local AFTER
12022         local idx
12023
12024         test_mkdir $dir
12025         #use setstripe to do a write to every ost
12026         for i in $(seq 0 $((OSTCOUNT-1))); do
12027                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12028                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12029                 idx=$(printf %04x $i)
12030                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12031                         awk '$1 == "cache_access" {sum += $7}
12032                                 END { printf("%0.0f", sum) }')
12033
12034                 cancel_lru_locks osc
12035                 cat $file >/dev/null
12036
12037                 AFTER=$(get_osd_param $list *OST*$idx stats |
12038                         awk '$1 == "cache_access" {sum += $7}
12039                                 END { printf("%0.0f", sum) }')
12040
12041                 echo BEFORE:$BEFORE AFTER:$AFTER
12042                 if ! let "AFTER - BEFORE == 4"; then
12043                         rm -rf $dir
12044                         error "roc_hit is not safe to use"
12045                 fi
12046                 rm $file
12047         done
12048
12049         rm -rf $dir
12050 }
12051
12052 function roc_hit() {
12053         local list=$(comma_list $(osts_nodes))
12054         echo $(get_osd_param $list '' stats |
12055                 awk '$1 == "cache_hit" {sum += $7}
12056                         END { printf("%0.0f", sum) }')
12057 }
12058
12059 function set_cache() {
12060         local on=1
12061
12062         if [ "$2" == "off" ]; then
12063                 on=0;
12064         fi
12065         local list=$(comma_list $(osts_nodes))
12066         set_osd_param $list '' $1_cache_enable $on
12067
12068         cancel_lru_locks osc
12069 }
12070
12071 test_151() {
12072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12073         remote_ost_nodsh && skip "remote OST with nodsh"
12074
12075         local CPAGES=3
12076         local list=$(comma_list $(osts_nodes))
12077
12078         # check whether obdfilter is cache capable at all
12079         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12080                 skip "not cache-capable obdfilter"
12081         fi
12082
12083         # check cache is enabled on all obdfilters
12084         if get_osd_param $list '' read_cache_enable | grep 0; then
12085                 skip "oss cache is disabled"
12086         fi
12087
12088         set_osd_param $list '' writethrough_cache_enable 1
12089
12090         # check write cache is enabled on all obdfilters
12091         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12092                 skip "oss write cache is NOT enabled"
12093         fi
12094
12095         roc_hit_init
12096
12097         #define OBD_FAIL_OBD_NO_LRU  0x609
12098         do_nodes $list $LCTL set_param fail_loc=0x609
12099
12100         # pages should be in the case right after write
12101         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12102                 error "dd failed"
12103
12104         local BEFORE=$(roc_hit)
12105         cancel_lru_locks osc
12106         cat $DIR/$tfile >/dev/null
12107         local AFTER=$(roc_hit)
12108
12109         do_nodes $list $LCTL set_param fail_loc=0
12110
12111         if ! let "AFTER - BEFORE == CPAGES"; then
12112                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12113         fi
12114
12115         # the following read invalidates the cache
12116         cancel_lru_locks osc
12117         set_osd_param $list '' read_cache_enable 0
12118         cat $DIR/$tfile >/dev/null
12119
12120         # now data shouldn't be found in the cache
12121         BEFORE=$(roc_hit)
12122         cancel_lru_locks osc
12123         cat $DIR/$tfile >/dev/null
12124         AFTER=$(roc_hit)
12125         if let "AFTER - BEFORE != 0"; then
12126                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12127         fi
12128
12129         set_osd_param $list '' read_cache_enable 1
12130         rm -f $DIR/$tfile
12131 }
12132 run_test 151 "test cache on oss and controls ==============================="
12133
12134 test_152() {
12135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12136
12137         local TF="$TMP/$tfile"
12138
12139         # simulate ENOMEM during write
12140 #define OBD_FAIL_OST_NOMEM      0x226
12141         lctl set_param fail_loc=0x80000226
12142         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12143         cp $TF $DIR/$tfile
12144         sync || error "sync failed"
12145         lctl set_param fail_loc=0
12146
12147         # discard client's cache
12148         cancel_lru_locks osc
12149
12150         # simulate ENOMEM during read
12151         lctl set_param fail_loc=0x80000226
12152         cmp $TF $DIR/$tfile || error "cmp failed"
12153         lctl set_param fail_loc=0
12154
12155         rm -f $TF
12156 }
12157 run_test 152 "test read/write with enomem ============================"
12158
12159 test_153() {
12160         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12161 }
12162 run_test 153 "test if fdatasync does not crash ======================="
12163
12164 dot_lustre_fid_permission_check() {
12165         local fid=$1
12166         local ffid=$MOUNT/.lustre/fid/$fid
12167         local test_dir=$2
12168
12169         echo "stat fid $fid"
12170         stat $ffid > /dev/null || error "stat $ffid failed."
12171         echo "touch fid $fid"
12172         touch $ffid || error "touch $ffid failed."
12173         echo "write to fid $fid"
12174         cat /etc/hosts > $ffid || error "write $ffid failed."
12175         echo "read fid $fid"
12176         diff /etc/hosts $ffid || error "read $ffid failed."
12177         echo "append write to fid $fid"
12178         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12179         echo "rename fid $fid"
12180         mv $ffid $test_dir/$tfile.1 &&
12181                 error "rename $ffid to $tfile.1 should fail."
12182         touch $test_dir/$tfile.1
12183         mv $test_dir/$tfile.1 $ffid &&
12184                 error "rename $tfile.1 to $ffid should fail."
12185         rm -f $test_dir/$tfile.1
12186         echo "truncate fid $fid"
12187         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12188         echo "link fid $fid"
12189         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12190         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12191                 echo "setfacl fid $fid"
12192                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12193                 echo "getfacl fid $fid"
12194                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12195         fi
12196         echo "unlink fid $fid"
12197         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12198         echo "mknod fid $fid"
12199         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12200
12201         fid=[0xf00000400:0x1:0x0]
12202         ffid=$MOUNT/.lustre/fid/$fid
12203
12204         echo "stat non-exist fid $fid"
12205         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12206         echo "write to non-exist fid $fid"
12207         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12208         echo "link new fid $fid"
12209         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12210
12211         mkdir -p $test_dir/$tdir
12212         touch $test_dir/$tdir/$tfile
12213         fid=$($LFS path2fid $test_dir/$tdir)
12214         rc=$?
12215         [ $rc -ne 0 ] &&
12216                 error "error: could not get fid for $test_dir/$dir/$tfile."
12217
12218         ffid=$MOUNT/.lustre/fid/$fid
12219
12220         echo "ls $fid"
12221         ls $ffid > /dev/null || error "ls $ffid failed."
12222         echo "touch $fid/$tfile.1"
12223         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12224
12225         echo "touch $MOUNT/.lustre/fid/$tfile"
12226         touch $MOUNT/.lustre/fid/$tfile && \
12227                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12228
12229         echo "setxattr to $MOUNT/.lustre/fid"
12230         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12231
12232         echo "listxattr for $MOUNT/.lustre/fid"
12233         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12234
12235         echo "delxattr from $MOUNT/.lustre/fid"
12236         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12237
12238         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12239         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12240                 error "touch invalid fid should fail."
12241
12242         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12243         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12244                 error "touch non-normal fid should fail."
12245
12246         echo "rename $tdir to $MOUNT/.lustre/fid"
12247         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12248                 error "rename to $MOUNT/.lustre/fid should fail."
12249
12250         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12251         then            # LU-3547
12252                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12253                 local new_obf_mode=777
12254
12255                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12256                 chmod $new_obf_mode $DIR/.lustre/fid ||
12257                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12258
12259                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12260                 [ $obf_mode -eq $new_obf_mode ] ||
12261                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12262
12263                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12264                 chmod $old_obf_mode $DIR/.lustre/fid ||
12265                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12266         fi
12267
12268         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12269         fid=$($LFS path2fid $test_dir/$tfile-2)
12270
12271         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12272         then # LU-5424
12273                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12274                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12275                         error "create lov data thru .lustre failed"
12276         fi
12277         echo "cp /etc/passwd $test_dir/$tfile-2"
12278         cp /etc/passwd $test_dir/$tfile-2 ||
12279                 error "copy to $test_dir/$tfile-2 failed."
12280         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12281         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12282                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12283
12284         rm -rf $test_dir/tfile.lnk
12285         rm -rf $test_dir/$tfile-2
12286 }
12287
12288 test_154A() {
12289         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12290                 skip "Need MDS version at least 2.4.1"
12291
12292         local tf=$DIR/$tfile
12293         touch $tf
12294
12295         local fid=$($LFS path2fid $tf)
12296         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12297
12298         # check that we get the same pathname back
12299         local found=$($LFS fid2path $MOUNT "$fid")
12300         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12301         [ "$found" == "$tf" ] ||
12302                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12303 }
12304 run_test 154A "lfs path2fid and fid2path basic checks"
12305
12306 test_154B() {
12307         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12308                 skip "Need MDS version at least 2.4.1"
12309
12310         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12311         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12312         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12313         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12314
12315         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12316         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12317
12318         # check that we get the same pathname
12319         echo "PFID: $PFID, name: $name"
12320         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12321         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12322         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12323                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12324
12325         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12326 }
12327 run_test 154B "verify the ll_decode_linkea tool"
12328
12329 test_154a() {
12330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12331         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12332         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12333                 skip "Need MDS version at least 2.2.51"
12334         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12335
12336         cp /etc/hosts $DIR/$tfile
12337
12338         fid=$($LFS path2fid $DIR/$tfile)
12339         rc=$?
12340         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
12341
12342         dot_lustre_fid_permission_check "$fid" $DIR ||
12343                 error "dot lustre permission check $fid failed"
12344
12345         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
12346
12347         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
12348
12349         touch $MOUNT/.lustre/file &&
12350                 error "creation is not allowed under .lustre"
12351
12352         mkdir $MOUNT/.lustre/dir &&
12353                 error "mkdir is not allowed under .lustre"
12354
12355         rm -rf $DIR/$tfile
12356 }
12357 run_test 154a "Open-by-FID"
12358
12359 test_154b() {
12360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12361         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12363         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12364                 skip "Need MDS version at least 2.2.51"
12365
12366         local remote_dir=$DIR/$tdir/remote_dir
12367         local MDTIDX=1
12368         local rc=0
12369
12370         mkdir -p $DIR/$tdir
12371         $LFS mkdir -i $MDTIDX $remote_dir ||
12372                 error "create remote directory failed"
12373
12374         cp /etc/hosts $remote_dir/$tfile
12375
12376         fid=$($LFS path2fid $remote_dir/$tfile)
12377         rc=$?
12378         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
12379
12380         dot_lustre_fid_permission_check "$fid" $remote_dir ||
12381                 error "dot lustre permission check $fid failed"
12382         rm -rf $DIR/$tdir
12383 }
12384 run_test 154b "Open-by-FID for remote directory"
12385
12386 test_154c() {
12387         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12388                 skip "Need MDS version at least 2.4.1"
12389
12390         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
12391         local FID1=$($LFS path2fid $DIR/$tfile.1)
12392         local FID2=$($LFS path2fid $DIR/$tfile.2)
12393         local FID3=$($LFS path2fid $DIR/$tfile.3)
12394
12395         local N=1
12396         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
12397                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
12398                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
12399                 local want=FID$N
12400                 [ "$FID" = "${!want}" ] ||
12401                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
12402                 N=$((N + 1))
12403         done
12404
12405         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
12406         do
12407                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
12408                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
12409                 N=$((N + 1))
12410         done
12411 }
12412 run_test 154c "lfs path2fid and fid2path multiple arguments"
12413
12414 test_154d() {
12415         remote_mds_nodsh && skip "remote MDS with nodsh"
12416         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
12417                 skip "Need MDS version at least 2.5.53"
12418
12419         if remote_mds; then
12420                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
12421         else
12422                 nid="0@lo"
12423         fi
12424         local proc_ofile="mdt.*.exports.'$nid'.open_files"
12425         local fd
12426         local cmd
12427
12428         rm -f $DIR/$tfile
12429         touch $DIR/$tfile
12430
12431         local fid=$($LFS path2fid $DIR/$tfile)
12432         # Open the file
12433         fd=$(free_fd)
12434         cmd="exec $fd<$DIR/$tfile"
12435         eval $cmd
12436         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
12437         echo "$fid_list" | grep "$fid"
12438         rc=$?
12439
12440         cmd="exec $fd>/dev/null"
12441         eval $cmd
12442         if [ $rc -ne 0 ]; then
12443                 error "FID $fid not found in open files list $fid_list"
12444         fi
12445 }
12446 run_test 154d "Verify open file fid"
12447
12448 test_154e()
12449 {
12450         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12451                 skip "Need MDS version at least 2.6.50"
12452
12453         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12454                 error ".lustre returned by readdir"
12455         fi
12456 }
12457 run_test 154e ".lustre is not returned by readdir"
12458
12459 test_154f() {
12460         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12461
12462         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12463         test_mkdir -p -c1 $DIR/$tdir/d
12464         # test dirs inherit from its stripe
12465         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12466         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12467         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12468         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12469         touch $DIR/f
12470
12471         # get fid of parents
12472         local FID0=$($LFS path2fid $DIR/$tdir/d)
12473         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12474         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12475         local FID3=$($LFS path2fid $DIR)
12476
12477         # check that path2fid --parents returns expected <parent_fid>/name
12478         # 1) test for a directory (single parent)
12479         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12480         [ "$parent" == "$FID0/foo1" ] ||
12481                 error "expected parent: $FID0/foo1, got: $parent"
12482
12483         # 2) test for a file with nlink > 1 (multiple parents)
12484         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12485         echo "$parent" | grep -F "$FID1/$tfile" ||
12486                 error "$FID1/$tfile not returned in parent list"
12487         echo "$parent" | grep -F "$FID2/link" ||
12488                 error "$FID2/link not returned in parent list"
12489
12490         # 3) get parent by fid
12491         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12492         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12493         echo "$parent" | grep -F "$FID1/$tfile" ||
12494                 error "$FID1/$tfile not returned in parent list (by fid)"
12495         echo "$parent" | grep -F "$FID2/link" ||
12496                 error "$FID2/link not returned in parent list (by fid)"
12497
12498         # 4) test for entry in root directory
12499         parent=$($LFS path2fid --parents $DIR/f)
12500         echo "$parent" | grep -F "$FID3/f" ||
12501                 error "$FID3/f not returned in parent list"
12502
12503         # 5) test it on root directory
12504         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12505                 error "$MOUNT should not have parents"
12506
12507         # enable xattr caching and check that linkea is correctly updated
12508         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12509         save_lustre_params client "llite.*.xattr_cache" > $save
12510         lctl set_param llite.*.xattr_cache 1
12511
12512         # 6.1) linkea update on rename
12513         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12514
12515         # get parents by fid
12516         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12517         # foo1 should no longer be returned in parent list
12518         echo "$parent" | grep -F "$FID1" &&
12519                 error "$FID1 should no longer be in parent list"
12520         # the new path should appear
12521         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12522                 error "$FID2/$tfile.moved is not in parent list"
12523
12524         # 6.2) linkea update on unlink
12525         rm -f $DIR/$tdir/d/foo2/link
12526         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12527         # foo2/link should no longer be returned in parent list
12528         echo "$parent" | grep -F "$FID2/link" &&
12529                 error "$FID2/link should no longer be in parent list"
12530         true
12531
12532         rm -f $DIR/f
12533         restore_lustre_params < $save
12534         rm -f $save
12535 }
12536 run_test 154f "get parent fids by reading link ea"
12537
12538 test_154g()
12539 {
12540         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12541         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12542            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12543                 skip "Need MDS version at least 2.6.92"
12544
12545         mkdir -p $DIR/$tdir
12546         llapi_fid_test -d $DIR/$tdir
12547 }
12548 run_test 154g "various llapi FID tests"
12549
12550 test_155_small_load() {
12551     local temp=$TMP/$tfile
12552     local file=$DIR/$tfile
12553
12554     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12555         error "dd of=$temp bs=6096 count=1 failed"
12556     cp $temp $file
12557     cancel_lru_locks $OSC
12558     cmp $temp $file || error "$temp $file differ"
12559
12560     $TRUNCATE $temp 6000
12561     $TRUNCATE $file 6000
12562     cmp $temp $file || error "$temp $file differ (truncate1)"
12563
12564     echo "12345" >>$temp
12565     echo "12345" >>$file
12566     cmp $temp $file || error "$temp $file differ (append1)"
12567
12568     echo "12345" >>$temp
12569     echo "12345" >>$file
12570     cmp $temp $file || error "$temp $file differ (append2)"
12571
12572     rm -f $temp $file
12573     true
12574 }
12575
12576 test_155_big_load() {
12577         remote_ost_nodsh && skip "remote OST with nodsh"
12578
12579         local temp=$TMP/$tfile
12580         local file=$DIR/$tfile
12581
12582         free_min_max
12583         local cache_size=$(do_facet ost$((MAXI+1)) \
12584                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12585         local large_file_size=$((cache_size * 2))
12586
12587         echo "OSS cache size: $cache_size KB"
12588         echo "Large file size: $large_file_size KB"
12589
12590         [ $MAXV -le $large_file_size ] &&
12591                 skip_env "max available OST size needs > $large_file_size KB"
12592
12593         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12594
12595         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12596                 error "dd of=$temp bs=$large_file_size count=1k failed"
12597         cp $temp $file
12598         ls -lh $temp $file
12599         cancel_lru_locks osc
12600         cmp $temp $file || error "$temp $file differ"
12601
12602         rm -f $temp $file
12603         true
12604 }
12605
12606 save_writethrough() {
12607         local facets=$(get_facets OST)
12608
12609         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12610 }
12611
12612 test_155a() {
12613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12614
12615         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12616
12617         save_writethrough $p
12618
12619         set_cache read on
12620         set_cache writethrough on
12621         test_155_small_load
12622         restore_lustre_params < $p
12623         rm -f $p
12624 }
12625 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12626
12627 test_155b() {
12628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12629
12630         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12631
12632         save_writethrough $p
12633
12634         set_cache read on
12635         set_cache writethrough off
12636         test_155_small_load
12637         restore_lustre_params < $p
12638         rm -f $p
12639 }
12640 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12641
12642 test_155c() {
12643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12644
12645         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12646
12647         save_writethrough $p
12648
12649         set_cache read off
12650         set_cache writethrough on
12651         test_155_small_load
12652         restore_lustre_params < $p
12653         rm -f $p
12654 }
12655 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12656
12657 test_155d() {
12658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12659
12660         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12661
12662         save_writethrough $p
12663
12664         set_cache read off
12665         set_cache writethrough off
12666         test_155_small_load
12667         restore_lustre_params < $p
12668         rm -f $p
12669 }
12670 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12671
12672 test_155e() {
12673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12674
12675         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12676
12677         save_writethrough $p
12678
12679         set_cache read on
12680         set_cache writethrough on
12681         test_155_big_load
12682         restore_lustre_params < $p
12683         rm -f $p
12684 }
12685 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12686
12687 test_155f() {
12688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12689
12690         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12691
12692         save_writethrough $p
12693
12694         set_cache read on
12695         set_cache writethrough off
12696         test_155_big_load
12697         restore_lustre_params < $p
12698         rm -f $p
12699 }
12700 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12701
12702 test_155g() {
12703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12704
12705         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12706
12707         save_writethrough $p
12708
12709         set_cache read off
12710         set_cache writethrough on
12711         test_155_big_load
12712         restore_lustre_params < $p
12713         rm -f $p
12714 }
12715 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12716
12717 test_155h() {
12718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12719
12720         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12721
12722         save_writethrough $p
12723
12724         set_cache read off
12725         set_cache writethrough off
12726         test_155_big_load
12727         restore_lustre_params < $p
12728         rm -f $p
12729 }
12730 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12731
12732 test_156() {
12733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12734         remote_ost_nodsh && skip "remote OST with nodsh"
12735         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12736                 skip "stats not implemented on old servers"
12737         [ "$ost1_FSTYPE" = "zfs" ] &&
12738                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12739
12740         local CPAGES=3
12741         local BEFORE
12742         local AFTER
12743         local file="$DIR/$tfile"
12744         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12745
12746         save_writethrough $p
12747         roc_hit_init
12748
12749         log "Turn on read and write cache"
12750         set_cache read on
12751         set_cache writethrough on
12752
12753         log "Write data and read it back."
12754         log "Read should be satisfied from the cache."
12755         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12756         BEFORE=$(roc_hit)
12757         cancel_lru_locks osc
12758         cat $file >/dev/null
12759         AFTER=$(roc_hit)
12760         if ! let "AFTER - BEFORE == CPAGES"; then
12761                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12762         else
12763                 log "cache hits:: before: $BEFORE, after: $AFTER"
12764         fi
12765
12766         log "Read again; it should be satisfied from the cache."
12767         BEFORE=$AFTER
12768         cancel_lru_locks osc
12769         cat $file >/dev/null
12770         AFTER=$(roc_hit)
12771         if ! let "AFTER - BEFORE == CPAGES"; then
12772                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12773         else
12774                 log "cache hits:: before: $BEFORE, after: $AFTER"
12775         fi
12776
12777         log "Turn off the read cache and turn on the write cache"
12778         set_cache read off
12779         set_cache writethrough on
12780
12781         log "Read again; it should be satisfied from the cache."
12782         BEFORE=$(roc_hit)
12783         cancel_lru_locks osc
12784         cat $file >/dev/null
12785         AFTER=$(roc_hit)
12786         if ! let "AFTER - BEFORE == CPAGES"; then
12787                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12788         else
12789                 log "cache hits:: before: $BEFORE, after: $AFTER"
12790         fi
12791
12792         log "Read again; it should not be satisfied from the cache."
12793         BEFORE=$AFTER
12794         cancel_lru_locks osc
12795         cat $file >/dev/null
12796         AFTER=$(roc_hit)
12797         if ! let "AFTER - BEFORE == 0"; then
12798                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12799         else
12800                 log "cache hits:: before: $BEFORE, after: $AFTER"
12801         fi
12802
12803         log "Write data and read it back."
12804         log "Read should be satisfied from the cache."
12805         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12806         BEFORE=$(roc_hit)
12807         cancel_lru_locks osc
12808         cat $file >/dev/null
12809         AFTER=$(roc_hit)
12810         if ! let "AFTER - BEFORE == CPAGES"; then
12811                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12812         else
12813                 log "cache hits:: before: $BEFORE, after: $AFTER"
12814         fi
12815
12816         log "Read again; it should not be satisfied from the cache."
12817         BEFORE=$AFTER
12818         cancel_lru_locks osc
12819         cat $file >/dev/null
12820         AFTER=$(roc_hit)
12821         if ! let "AFTER - BEFORE == 0"; then
12822                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12823         else
12824                 log "cache hits:: before: $BEFORE, after: $AFTER"
12825         fi
12826
12827         log "Turn off read and write cache"
12828         set_cache read off
12829         set_cache writethrough off
12830
12831         log "Write data and read it back"
12832         log "It should not be satisfied from the cache."
12833         rm -f $file
12834         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12835         cancel_lru_locks osc
12836         BEFORE=$(roc_hit)
12837         cat $file >/dev/null
12838         AFTER=$(roc_hit)
12839         if ! let "AFTER - BEFORE == 0"; then
12840                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12841         else
12842                 log "cache hits:: before: $BEFORE, after: $AFTER"
12843         fi
12844
12845         log "Turn on the read cache and turn off the write cache"
12846         set_cache read on
12847         set_cache writethrough off
12848
12849         log "Write data and read it back"
12850         log "It should not be satisfied from the cache."
12851         rm -f $file
12852         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12853         BEFORE=$(roc_hit)
12854         cancel_lru_locks osc
12855         cat $file >/dev/null
12856         AFTER=$(roc_hit)
12857         if ! let "AFTER - BEFORE == 0"; then
12858                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12859         else
12860                 log "cache hits:: before: $BEFORE, after: $AFTER"
12861         fi
12862
12863         log "Read again; it should be satisfied from the cache."
12864         BEFORE=$(roc_hit)
12865         cancel_lru_locks osc
12866         cat $file >/dev/null
12867         AFTER=$(roc_hit)
12868         if ! let "AFTER - BEFORE == CPAGES"; then
12869                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12870         else
12871                 log "cache hits:: before: $BEFORE, after: $AFTER"
12872         fi
12873
12874         restore_lustre_params < $p
12875         rm -f $p $file
12876 }
12877 run_test 156 "Verification of tunables"
12878
12879 test_160a() {
12880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12881         remote_mds_nodsh && skip "remote MDS with nodsh"
12882         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12883                 skip "Need MDS version at least 2.2.0"
12884
12885         changelog_register || error "changelog_register failed"
12886         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12887         changelog_users $SINGLEMDS | grep -q $cl_user ||
12888                 error "User $cl_user not found in changelog_users"
12889
12890         # change something
12891         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12892         changelog_clear 0 || error "changelog_clear failed"
12893         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12894         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12895         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12896         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12897         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12898         rm $DIR/$tdir/pics/desktop.jpg
12899
12900         changelog_dump | tail -10
12901
12902         echo "verifying changelog mask"
12903         changelog_chmask "-MKDIR"
12904         changelog_chmask "-CLOSE"
12905
12906         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12907         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12908
12909         changelog_chmask "+MKDIR"
12910         changelog_chmask "+CLOSE"
12911
12912         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12913         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12914
12915         changelog_dump | tail -10
12916         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12917         CLOSES=$(changelog_dump | grep -c "CLOSE")
12918         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12919         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12920
12921         # verify contents
12922         echo "verifying target fid"
12923         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12924         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12925         [ "$fidc" == "$fidf" ] ||
12926                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12927         echo "verifying parent fid"
12928         # The FID returned from the Changelog may be the directory shard on
12929         # a different MDT, and not the FID returned by path2fid on the parent.
12930         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12931         # since this is what will matter when recreating this file in the tree.
12932         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12933         local pathp=$($LFS fid2path $MOUNT "$fidp")
12934         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12935                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12936
12937         echo "getting records for $cl_user"
12938         changelog_users $SINGLEMDS
12939         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12940         local nclr=3
12941         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12942                 error "changelog_clear failed"
12943         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12944         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12945         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12946                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12947
12948         local min0_rec=$(changelog_users $SINGLEMDS |
12949                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12950         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12951                           awk '{ print $1; exit; }')
12952
12953         changelog_dump | tail -n 5
12954         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12955         [ $first_rec == $((min0_rec + 1)) ] ||
12956                 error "first index should be $min0_rec + 1 not $first_rec"
12957
12958         # LU-3446 changelog index reset on MDT restart
12959         local cur_rec1=$(changelog_users $SINGLEMDS |
12960                          awk '/^current.index:/ { print $NF }')
12961         changelog_clear 0 ||
12962                 error "clear all changelog records for $cl_user failed"
12963         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12964         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12965                 error "Fail to start $SINGLEMDS"
12966         local cur_rec2=$(changelog_users $SINGLEMDS |
12967                          awk '/^current.index:/ { print $NF }')
12968         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12969         [ $cur_rec1 == $cur_rec2 ] ||
12970                 error "current index should be $cur_rec1 not $cur_rec2"
12971
12972         echo "verifying users from this test are deregistered"
12973         changelog_deregister || error "changelog_deregister failed"
12974         changelog_users $SINGLEMDS | grep -q $cl_user &&
12975                 error "User '$cl_user' still in changelog_users"
12976
12977         # lctl get_param -n mdd.*.changelog_users
12978         # current index: 144
12979         # ID    index (idle seconds)
12980         # cl3   144 (2)
12981         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12982                 # this is the normal case where all users were deregistered
12983                 # make sure no new records are added when no users are present
12984                 local last_rec1=$(changelog_users $SINGLEMDS |
12985                                   awk '/^current.index:/ { print $NF }')
12986                 touch $DIR/$tdir/chloe
12987                 local last_rec2=$(changelog_users $SINGLEMDS |
12988                                   awk '/^current.index:/ { print $NF }')
12989                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
12990                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
12991         else
12992                 # any changelog users must be leftovers from a previous test
12993                 changelog_users $SINGLEMDS
12994                 echo "other changelog users; can't verify off"
12995         fi
12996 }
12997 run_test 160a "changelog sanity"
12998
12999 test_160b() { # LU-3587
13000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13001         remote_mds_nodsh && skip "remote MDS with nodsh"
13002         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13003                 skip "Need MDS version at least 2.2.0"
13004
13005         changelog_register || error "changelog_register failed"
13006         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13007         changelog_users $SINGLEMDS | grep -q $cl_user ||
13008                 error "User '$cl_user' not found in changelog_users"
13009
13010         local longname1=$(str_repeat a 255)
13011         local longname2=$(str_repeat b 255)
13012
13013         cd $DIR
13014         echo "creating very long named file"
13015         touch $longname1 || error "create of '$longname1' failed"
13016         echo "renaming very long named file"
13017         mv $longname1 $longname2
13018
13019         changelog_dump | grep RENME | tail -n 5
13020         rm -f $longname2
13021 }
13022 run_test 160b "Verify that very long rename doesn't crash in changelog"
13023
13024 test_160c() {
13025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13026         remote_mds_nodsh && skip "remote MDS with nodsh"
13027
13028         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13029                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13030                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13031                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13032
13033         local rc=0
13034
13035         # Registration step
13036         changelog_register || error "changelog_register failed"
13037
13038         rm -rf $DIR/$tdir
13039         mkdir -p $DIR/$tdir
13040         $MCREATE $DIR/$tdir/foo_160c
13041         changelog_chmask "-TRUNC"
13042         $TRUNCATE $DIR/$tdir/foo_160c 200
13043         changelog_chmask "+TRUNC"
13044         $TRUNCATE $DIR/$tdir/foo_160c 199
13045         changelog_dump | tail -n 5
13046         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13047         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13048 }
13049 run_test 160c "verify that changelog log catch the truncate event"
13050
13051 test_160d() {
13052         remote_mds_nodsh && skip "remote MDS with nodsh"
13053         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13055         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13056                 skip "Need MDS version at least 2.7.60"
13057
13058         # Registration step
13059         changelog_register || error "changelog_register failed"
13060
13061         mkdir -p $DIR/$tdir/migrate_dir
13062         changelog_clear 0 || error "changelog_clear failed"
13063
13064         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13065         changelog_dump | tail -n 5
13066         local migrates=$(changelog_dump | grep -c "MIGRT")
13067         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13068 }
13069 run_test 160d "verify that changelog log catch the migrate event"
13070
13071 test_160e() {
13072         remote_mds_nodsh && skip "remote MDS with nodsh"
13073
13074         # Create a user
13075         changelog_register || error "changelog_register failed"
13076
13077         # Delete a future user (expect fail)
13078         local MDT0=$(facet_svc $SINGLEMDS)
13079         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13080         local rc=$?
13081
13082         if [ $rc -eq 0 ]; then
13083                 error "Deleted non-existant user cl77"
13084         elif [ $rc -ne 2 ]; then
13085                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13086         fi
13087
13088         # Clear to a bad index (1 billion should be safe)
13089         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13090         rc=$?
13091
13092         if [ $rc -eq 0 ]; then
13093                 error "Successfully cleared to invalid CL index"
13094         elif [ $rc -ne 22 ]; then
13095                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13096         fi
13097 }
13098 run_test 160e "changelog negative testing (should return errors)"
13099
13100 test_160f() {
13101         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13102         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13103                 skip "Need MDS version at least 2.10.56"
13104
13105         local mdts=$(comma_list $(mdts_nodes))
13106
13107         # Create a user
13108         changelog_register || error "first changelog_register failed"
13109         changelog_register || error "second changelog_register failed"
13110         local cl_users
13111         declare -A cl_user1
13112         declare -A cl_user2
13113         local user_rec1
13114         local user_rec2
13115         local i
13116
13117         # generate some changelog records to accumulate on each MDT
13118         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13119         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13120                 error "create $DIR/$tdir/$tfile failed"
13121
13122         # check changelogs have been generated
13123         local nbcl=$(changelog_dump | wc -l)
13124         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13125
13126         for param in "changelog_max_idle_time=10" \
13127                      "changelog_gc=1" \
13128                      "changelog_min_gc_interval=2" \
13129                      "changelog_min_free_cat_entries=3"; do
13130                 local MDT0=$(facet_svc $SINGLEMDS)
13131                 local var="${param%=*}"
13132                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13133
13134                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13135                 do_nodes $mdts $LCTL set_param mdd.*.$param
13136         done
13137
13138         # force cl_user2 to be idle (1st part)
13139         sleep 9
13140
13141         # simulate changelog catalog almost full
13142         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13143         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13144
13145         for i in $(seq $MDSCOUNT); do
13146                 cl_users=(${CL_USERS[mds$i]})
13147                 cl_user1[mds$i]="${cl_users[0]}"
13148                 cl_user2[mds$i]="${cl_users[1]}"
13149
13150                 [ -n "${cl_user1[mds$i]}" ] ||
13151                         error "mds$i: no user registered"
13152                 [ -n "${cl_user2[mds$i]}" ] ||
13153                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13154
13155                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13156                 [ -n "$user_rec1" ] ||
13157                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13158                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13159                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13160                 [ -n "$user_rec2" ] ||
13161                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13162                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13163                      "$user_rec1 + 2 == $user_rec2"
13164                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13165                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13166                               "$user_rec1 + 2, but is $user_rec2"
13167                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13168                 [ -n "$user_rec2" ] ||
13169                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13170                 [ $user_rec1 == $user_rec2 ] ||
13171                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13172                               "$user_rec1, but is $user_rec2"
13173         done
13174
13175         # force cl_user2 to be idle (2nd part) and to reach
13176         # changelog_max_idle_time
13177         sleep 2
13178
13179         # generate one more changelog to trigger fail_loc
13180         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13181                 error "create $DIR/$tdir/${tfile}bis failed"
13182
13183         # ensure gc thread is done
13184         for i in $(mdts_nodes); do
13185                 wait_update $i \
13186                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13187                         error "$i: GC-thread not done"
13188         done
13189
13190         local first_rec
13191         for i in $(seq $MDSCOUNT); do
13192                 # check cl_user1 still registered
13193                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13194                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13195                 # check cl_user2 unregistered
13196                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13197                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13198
13199                 # check changelogs are present and starting at $user_rec1 + 1
13200                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13201                 [ -n "$user_rec1" ] ||
13202                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13203                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13204                             awk '{ print $1; exit; }')
13205
13206                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13207                 [ $((user_rec1 + 1)) == $first_rec ] ||
13208                         error "mds$i: first index should be $user_rec1 + 1, " \
13209                               "but is $first_rec"
13210         done
13211 }
13212 run_test 160f "changelog garbage collect (timestamped users)"
13213
13214 test_160g() {
13215         remote_mds_nodsh && skip "remote MDS with nodsh"
13216         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13217                 skip "Need MDS version at least 2.10.56"
13218
13219         local mdts=$(comma_list $(mdts_nodes))
13220
13221         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13222         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13223
13224         # Create a user
13225         changelog_register || error "first changelog_register failed"
13226         changelog_register || error "second changelog_register failed"
13227         local cl_users
13228         declare -A cl_user1
13229         declare -A cl_user2
13230         local user_rec1
13231         local user_rec2
13232         local i
13233
13234         # generate some changelog records to accumulate on each MDT
13235         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13236         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13237                 error "create $DIR/$tdir/$tfile failed"
13238
13239         # check changelogs have been generated
13240         local nbcl=$(changelog_dump | wc -l)
13241         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13242
13243         # reduce the max_idle_indexes value to make sure we exceed it
13244         max_ndx=$((nbcl / 2 - 1))
13245
13246         for param in "changelog_max_idle_indexes=$max_ndx" \
13247                      "changelog_gc=1" \
13248                      "changelog_min_gc_interval=2" \
13249                      "changelog_min_free_cat_entries=3"; do
13250                 local MDT0=$(facet_svc $SINGLEMDS)
13251                 local var="${param%=*}"
13252                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13253
13254                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13255                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13256                         error "unable to set mdd.*.$param"
13257         done
13258
13259         # simulate changelog catalog almost full
13260         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13261         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13262
13263         for i in $(seq $MDSCOUNT); do
13264                 cl_users=(${CL_USERS[mds$i]})
13265                 cl_user1[mds$i]="${cl_users[0]}"
13266                 cl_user2[mds$i]="${cl_users[1]}"
13267
13268                 [ -n "${cl_user1[mds$i]}" ] ||
13269                         error "mds$i: no user registered"
13270                 [ -n "${cl_user2[mds$i]}" ] ||
13271                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13272
13273                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13274                 [ -n "$user_rec1" ] ||
13275                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13276                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13277                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13278                 [ -n "$user_rec2" ] ||
13279                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13280                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13281                      "$user_rec1 + 2 == $user_rec2"
13282                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13283                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13284                               "$user_rec1 + 2, but is $user_rec2"
13285                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13286                 [ -n "$user_rec2" ] ||
13287                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13288                 [ $user_rec1 == $user_rec2 ] ||
13289                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13290                               "$user_rec1, but is $user_rec2"
13291         done
13292
13293         # ensure we are past the previous changelog_min_gc_interval set above
13294         sleep 2
13295
13296         # generate one more changelog to trigger fail_loc
13297         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13298                 error "create $DIR/$tdir/${tfile}bis failed"
13299
13300         # ensure gc thread is done
13301         for i in $(mdts_nodes); do
13302                 wait_update $i \
13303                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13304                         error "$i: GC-thread not done"
13305         done
13306
13307         local first_rec
13308         for i in $(seq $MDSCOUNT); do
13309                 # check cl_user1 still registered
13310                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13311                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13312                 # check cl_user2 unregistered
13313                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13314                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13315
13316                 # check changelogs are present and starting at $user_rec1 + 1
13317                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13318                 [ -n "$user_rec1" ] ||
13319                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13320                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13321                             awk '{ print $1; exit; }')
13322
13323                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13324                 [ $((user_rec1 + 1)) == $first_rec ] ||
13325                         error "mds$i: first index should be $user_rec1 + 1, " \
13326                               "but is $first_rec"
13327         done
13328 }
13329 run_test 160g "changelog garbage collect (old users)"
13330
13331 test_160h() {
13332         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13333         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13334                 skip "Need MDS version at least 2.10.56"
13335
13336         local mdts=$(comma_list $(mdts_nodes))
13337
13338         # Create a user
13339         changelog_register || error "first changelog_register failed"
13340         changelog_register || error "second changelog_register failed"
13341         local cl_users
13342         declare -A cl_user1
13343         declare -A cl_user2
13344         local user_rec1
13345         local user_rec2
13346         local i
13347
13348         # generate some changelog records to accumulate on each MDT
13349         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13350         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13351                 error "create $DIR/$tdir/$tfile failed"
13352
13353         # check changelogs have been generated
13354         local nbcl=$(changelog_dump | wc -l)
13355         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13356
13357         for param in "changelog_max_idle_time=10" \
13358                      "changelog_gc=1" \
13359                      "changelog_min_gc_interval=2"; do
13360                 local MDT0=$(facet_svc $SINGLEMDS)
13361                 local var="${param%=*}"
13362                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13363
13364                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13365                 do_nodes $mdts $LCTL set_param mdd.*.$param
13366         done
13367
13368         # force cl_user2 to be idle (1st part)
13369         sleep 9
13370
13371         for i in $(seq $MDSCOUNT); do
13372                 cl_users=(${CL_USERS[mds$i]})
13373                 cl_user1[mds$i]="${cl_users[0]}"
13374                 cl_user2[mds$i]="${cl_users[1]}"
13375
13376                 [ -n "${cl_user1[mds$i]}" ] ||
13377                         error "mds$i: no user registered"
13378                 [ -n "${cl_user2[mds$i]}" ] ||
13379                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13380
13381                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13382                 [ -n "$user_rec1" ] ||
13383                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13384                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13385                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13386                 [ -n "$user_rec2" ] ||
13387                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13388                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13389                      "$user_rec1 + 2 == $user_rec2"
13390                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13391                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13392                               "$user_rec1 + 2, but is $user_rec2"
13393                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13394                 [ -n "$user_rec2" ] ||
13395                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13396                 [ $user_rec1 == $user_rec2 ] ||
13397                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13398                               "$user_rec1, but is $user_rec2"
13399         done
13400
13401         # force cl_user2 to be idle (2nd part) and to reach
13402         # changelog_max_idle_time
13403         sleep 2
13404
13405         # force each GC-thread start and block then
13406         # one per MDT/MDD, set fail_val accordingly
13407         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
13408         do_nodes $mdts $LCTL set_param fail_loc=0x1316
13409
13410         # generate more changelogs to trigger fail_loc
13411         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13412                 error "create $DIR/$tdir/${tfile}bis failed"
13413
13414         # stop MDT to stop GC-thread, should be done in back-ground as it will
13415         # block waiting for the thread to be released and exit
13416         declare -A stop_pids
13417         for i in $(seq $MDSCOUNT); do
13418                 stop mds$i &
13419                 stop_pids[mds$i]=$!
13420         done
13421
13422         for i in $(mdts_nodes); do
13423                 local facet
13424                 local nb=0
13425                 local facets=$(facets_up_on_host $i)
13426
13427                 for facet in ${facets//,/ }; do
13428                         if [[ $facet == mds* ]]; then
13429                                 nb=$((nb + 1))
13430                         fi
13431                 done
13432                 # ensure each MDS's gc threads are still present and all in "R"
13433                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
13434                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
13435                         error "$i: expected $nb GC-thread"
13436                 wait_update $i \
13437                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
13438                         "R" 20 ||
13439                         error "$i: GC-thread not found in R-state"
13440                 # check umounts of each MDT on MDS have reached kthread_stop()
13441                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
13442                         error "$i: expected $nb umount"
13443                 wait_update $i \
13444                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
13445                         error "$i: umount not found in D-state"
13446         done
13447
13448         # release all GC-threads
13449         do_nodes $mdts $LCTL set_param fail_loc=0
13450
13451         # wait for MDT stop to complete
13452         for i in $(seq $MDSCOUNT); do
13453                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13454         done
13455
13456         # XXX
13457         # may try to check if any orphan changelog records are present
13458         # via ldiskfs/zfs and llog_reader...
13459
13460         # re-start/mount MDTs
13461         for i in $(seq $MDSCOUNT); do
13462                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13463                         error "Fail to start mds$i"
13464         done
13465
13466         local first_rec
13467         for i in $(seq $MDSCOUNT); do
13468                 # check cl_user1 still registered
13469                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13470                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13471                 # check cl_user2 unregistered
13472                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13473                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13474
13475                 # check changelogs are present and starting at $user_rec1 + 1
13476                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13477                 [ -n "$user_rec1" ] ||
13478                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13479                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13480                             awk '{ print $1; exit; }')
13481
13482                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13483                 [ $((user_rec1 + 1)) == $first_rec ] ||
13484                         error "mds$i: first index should be $user_rec1 + 1, " \
13485                               "but is $first_rec"
13486         done
13487 }
13488 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13489               "during mount"
13490
13491 test_160i() {
13492
13493         local mdts=$(comma_list $(mdts_nodes))
13494
13495         changelog_register || error "first changelog_register failed"
13496
13497         # generate some changelog records to accumulate on each MDT
13498         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13499         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13500                 error "create $DIR/$tdir/$tfile failed"
13501
13502         # check changelogs have been generated
13503         local nbcl=$(changelog_dump | wc -l)
13504         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13505
13506         # simulate race between register and unregister
13507         # XXX as fail_loc is set per-MDS, with DNE configs the race
13508         # simulation will only occur for one MDT per MDS and for the
13509         # others the normal race scenario will take place
13510         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13511         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13512         do_nodes $mdts $LCTL set_param fail_val=1
13513
13514         # unregister 1st user
13515         changelog_deregister &
13516         local pid1=$!
13517         # wait some time for deregister work to reach race rdv
13518         sleep 2
13519         # register 2nd user
13520         changelog_register || error "2nd user register failed"
13521
13522         wait $pid1 || error "1st user deregister failed"
13523
13524         local i
13525         local last_rec
13526         declare -A LAST_REC
13527         for i in $(seq $MDSCOUNT); do
13528                 if changelog_users mds$i | grep "^cl"; then
13529                         # make sure new records are added with one user present
13530                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13531                                           awk '/^current.index:/ { print $NF }')
13532                 else
13533                         error "mds$i has no user registered"
13534                 fi
13535         done
13536
13537         # generate more changelog records to accumulate on each MDT
13538         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13539                 error "create $DIR/$tdir/${tfile}bis failed"
13540
13541         for i in $(seq $MDSCOUNT); do
13542                 last_rec=$(changelog_users $SINGLEMDS |
13543                            awk '/^current.index:/ { print $NF }')
13544                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13545                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13546                         error "changelogs are off on mds$i"
13547         done
13548 }
13549 run_test 160i "changelog user register/unregister race"
13550
13551 test_161a() {
13552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13553
13554         test_mkdir -c1 $DIR/$tdir
13555         cp /etc/hosts $DIR/$tdir/$tfile
13556         test_mkdir -c1 $DIR/$tdir/foo1
13557         test_mkdir -c1 $DIR/$tdir/foo2
13558         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13559         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13560         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13561         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13562         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13563         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13564                 $LFS fid2path $DIR $FID
13565                 error "bad link ea"
13566         fi
13567         # middle
13568         rm $DIR/$tdir/foo2/zachary
13569         # last
13570         rm $DIR/$tdir/foo2/thor
13571         # first
13572         rm $DIR/$tdir/$tfile
13573         # rename
13574         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13575         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13576                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13577         rm $DIR/$tdir/foo2/maggie
13578
13579         # overflow the EA
13580         local longname=$tfile.avg_len_is_thirty_two_
13581         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13582                 error_noexit 'failed to unlink many hardlinks'" EXIT
13583         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13584                 error "failed to hardlink many files"
13585         links=$($LFS fid2path $DIR $FID | wc -l)
13586         echo -n "${links}/1000 links in link EA"
13587         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13588 }
13589 run_test 161a "link ea sanity"
13590
13591 test_161b() {
13592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13593         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13594
13595         local MDTIDX=1
13596         local remote_dir=$DIR/$tdir/remote_dir
13597
13598         mkdir -p $DIR/$tdir
13599         $LFS mkdir -i $MDTIDX $remote_dir ||
13600                 error "create remote directory failed"
13601
13602         cp /etc/hosts $remote_dir/$tfile
13603         mkdir -p $remote_dir/foo1
13604         mkdir -p $remote_dir/foo2
13605         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13606         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13607         ln $remote_dir/$tfile $remote_dir/foo1/luna
13608         ln $remote_dir/$tfile $remote_dir/foo2/thor
13609
13610         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13611                      tr -d ']')
13612         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13613                 $LFS fid2path $DIR $FID
13614                 error "bad link ea"
13615         fi
13616         # middle
13617         rm $remote_dir/foo2/zachary
13618         # last
13619         rm $remote_dir/foo2/thor
13620         # first
13621         rm $remote_dir/$tfile
13622         # rename
13623         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13624         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13625         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13626                 $LFS fid2path $DIR $FID
13627                 error "bad link rename"
13628         fi
13629         rm $remote_dir/foo2/maggie
13630
13631         # overflow the EA
13632         local longname=filename_avg_len_is_thirty_two_
13633         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13634                 error "failed to hardlink many files"
13635         links=$($LFS fid2path $DIR $FID | wc -l)
13636         echo -n "${links}/1000 links in link EA"
13637         [[ ${links} -gt 60 ]] ||
13638                 error "expected at least 60 links in link EA"
13639         unlinkmany $remote_dir/foo2/$longname 1000 ||
13640         error "failed to unlink many hardlinks"
13641 }
13642 run_test 161b "link ea sanity under remote directory"
13643
13644 test_161c() {
13645         remote_mds_nodsh && skip "remote MDS with nodsh"
13646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13647         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13648                 skip "Need MDS version at least 2.1.5"
13649
13650         # define CLF_RENAME_LAST 0x0001
13651         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13652         changelog_register || error "changelog_register failed"
13653
13654         rm -rf $DIR/$tdir
13655         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13656         touch $DIR/$tdir/foo_161c
13657         touch $DIR/$tdir/bar_161c
13658         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13659         changelog_dump | grep RENME | tail -n 5
13660         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13661         changelog_clear 0 || error "changelog_clear failed"
13662         if [ x$flags != "x0x1" ]; then
13663                 error "flag $flags is not 0x1"
13664         fi
13665
13666         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13667         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13668         touch $DIR/$tdir/foo_161c
13669         touch $DIR/$tdir/bar_161c
13670         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13671         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13672         changelog_dump | grep RENME | tail -n 5
13673         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13674         changelog_clear 0 || error "changelog_clear failed"
13675         if [ x$flags != "x0x0" ]; then
13676                 error "flag $flags is not 0x0"
13677         fi
13678         echo "rename overwrite a target having nlink > 1," \
13679                 "changelog record has flags of $flags"
13680
13681         # rename doesn't overwrite a target (changelog flag 0x0)
13682         touch $DIR/$tdir/foo_161c
13683         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13684         changelog_dump | grep RENME | tail -n 5
13685         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13686         changelog_clear 0 || error "changelog_clear failed"
13687         if [ x$flags != "x0x0" ]; then
13688                 error "flag $flags is not 0x0"
13689         fi
13690         echo "rename doesn't overwrite a target," \
13691                 "changelog record has flags of $flags"
13692
13693         # define CLF_UNLINK_LAST 0x0001
13694         # unlink a file having nlink = 1 (changelog flag 0x1)
13695         rm -f $DIR/$tdir/foo2_161c
13696         changelog_dump | grep UNLNK | tail -n 5
13697         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13698         changelog_clear 0 || error "changelog_clear failed"
13699         if [ x$flags != "x0x1" ]; then
13700                 error "flag $flags is not 0x1"
13701         fi
13702         echo "unlink a file having nlink = 1," \
13703                 "changelog record has flags of $flags"
13704
13705         # unlink a file having nlink > 1 (changelog flag 0x0)
13706         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13707         rm -f $DIR/$tdir/foobar_161c
13708         changelog_dump | grep UNLNK | tail -n 5
13709         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13710         changelog_clear 0 || error "changelog_clear failed"
13711         if [ x$flags != "x0x0" ]; then
13712                 error "flag $flags is not 0x0"
13713         fi
13714         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13715 }
13716 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13717
13718 test_161d() {
13719         remote_mds_nodsh && skip "remote MDS with nodsh"
13720         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13721
13722         local pid
13723         local fid
13724
13725         changelog_register || error "changelog_register failed"
13726
13727         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13728         # interfer with $MOUNT/.lustre/fid/ access
13729         mkdir $DIR/$tdir
13730         [[ $? -eq 0 ]] || error "mkdir failed"
13731
13732         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13733         $LCTL set_param fail_loc=0x8000140c
13734         # 5s pause
13735         $LCTL set_param fail_val=5
13736
13737         # create file
13738         echo foofoo > $DIR/$tdir/$tfile &
13739         pid=$!
13740
13741         # wait for create to be delayed
13742         sleep 2
13743
13744         ps -p $pid
13745         [[ $? -eq 0 ]] || error "create should be blocked"
13746
13747         local tempfile=$(mktemp)
13748         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13749         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13750         # some delay may occur during ChangeLog publishing and file read just
13751         # above, that could allow file write to happen finally
13752         [[ -s $tempfile ]] && echo "file should be empty"
13753
13754         $LCTL set_param fail_loc=0
13755
13756         wait $pid
13757         [[ $? -eq 0 ]] || error "create failed"
13758 }
13759 run_test 161d "create with concurrent .lustre/fid access"
13760
13761 check_path() {
13762         local expected="$1"
13763         shift
13764         local fid="$2"
13765
13766         local path
13767         path=$($LFS fid2path "$@")
13768         local rc=$?
13769
13770         if [ $rc -ne 0 ]; then
13771                 error "path looked up of '$expected' failed: rc=$rc"
13772         elif [ "$path" != "$expected" ]; then
13773                 error "path looked up '$path' instead of '$expected'"
13774         else
13775                 echo "FID '$fid' resolves to path '$path' as expected"
13776         fi
13777 }
13778
13779 test_162a() { # was test_162
13780         test_mkdir -p -c1 $DIR/$tdir/d2
13781         touch $DIR/$tdir/d2/$tfile
13782         touch $DIR/$tdir/d2/x1
13783         touch $DIR/$tdir/d2/x2
13784         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13785         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13786         # regular file
13787         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13788         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13789
13790         # softlink
13791         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13792         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13793         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13794
13795         # softlink to wrong file
13796         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13797         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13798         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13799
13800         # hardlink
13801         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13802         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13803         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13804         # fid2path dir/fsname should both work
13805         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13806         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13807
13808         # hardlink count: check that there are 2 links
13809         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13810         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13811
13812         # hardlink indexing: remove the first link
13813         rm $DIR/$tdir/d2/p/q/r/hlink
13814         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13815 }
13816 run_test 162a "path lookup sanity"
13817
13818 test_162b() {
13819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13820         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13821
13822         mkdir $DIR/$tdir
13823         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13824                                 error "create striped dir failed"
13825
13826         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13827                                         tail -n 1 | awk '{print $2}')
13828         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13829
13830         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13831         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13832
13833         # regular file
13834         for ((i=0;i<5;i++)); do
13835                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13836                         error "get fid for f$i failed"
13837                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13838
13839                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13840                         error "get fid for d$i failed"
13841                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13842         done
13843
13844         return 0
13845 }
13846 run_test 162b "striped directory path lookup sanity"
13847
13848 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13849 test_162c() {
13850         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13851                 skip "Need MDS version at least 2.7.51"
13852
13853         local lpath=$tdir.local
13854         local rpath=$tdir.remote
13855
13856         test_mkdir $DIR/$lpath
13857         test_mkdir $DIR/$rpath
13858
13859         for ((i = 0; i <= 101; i++)); do
13860                 lpath="$lpath/$i"
13861                 mkdir $DIR/$lpath
13862                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13863                         error "get fid for local directory $DIR/$lpath failed"
13864                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13865
13866                 rpath="$rpath/$i"
13867                 test_mkdir $DIR/$rpath
13868                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13869                         error "get fid for remote directory $DIR/$rpath failed"
13870                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13871         done
13872
13873         return 0
13874 }
13875 run_test 162c "fid2path works with paths 100 or more directories deep"
13876
13877 test_169() {
13878         # do directio so as not to populate the page cache
13879         log "creating a 10 Mb file"
13880         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13881         log "starting reads"
13882         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13883         log "truncating the file"
13884         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13885         log "killing dd"
13886         kill %+ || true # reads might have finished
13887         echo "wait until dd is finished"
13888         wait
13889         log "removing the temporary file"
13890         rm -rf $DIR/$tfile || error "tmp file removal failed"
13891 }
13892 run_test 169 "parallel read and truncate should not deadlock"
13893
13894 test_170() {
13895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13896
13897         $LCTL clear     # bug 18514
13898         $LCTL debug_daemon start $TMP/${tfile}_log_good
13899         touch $DIR/$tfile
13900         $LCTL debug_daemon stop
13901         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13902                 error "sed failed to read log_good"
13903
13904         $LCTL debug_daemon start $TMP/${tfile}_log_good
13905         rm -rf $DIR/$tfile
13906         $LCTL debug_daemon stop
13907
13908         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13909                error "lctl df log_bad failed"
13910
13911         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13912         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13913
13914         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13915         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13916
13917         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13918                 error "bad_line good_line1 good_line2 are empty"
13919
13920         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13921         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13922         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13923
13924         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13925         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13926         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13927
13928         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13929                 error "bad_line_new good_line_new are empty"
13930
13931         local expected_good=$((good_line1 + good_line2*2))
13932
13933         rm -f $TMP/${tfile}*
13934         # LU-231, short malformed line may not be counted into bad lines
13935         if [ $bad_line -ne $bad_line_new ] &&
13936                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13937                 error "expected $bad_line bad lines, but got $bad_line_new"
13938                 return 1
13939         fi
13940
13941         if [ $expected_good -ne $good_line_new ]; then
13942                 error "expected $expected_good good lines, but got $good_line_new"
13943                 return 2
13944         fi
13945         true
13946 }
13947 run_test 170 "test lctl df to handle corrupted log ====================="
13948
13949 test_171() { # bug20592
13950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13951
13952         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13953         $LCTL set_param fail_loc=0x50e
13954         $LCTL set_param fail_val=3000
13955         multiop_bg_pause $DIR/$tfile O_s || true
13956         local MULTIPID=$!
13957         kill -USR1 $MULTIPID
13958         # cause log dump
13959         sleep 3
13960         wait $MULTIPID
13961         if dmesg | grep "recursive fault"; then
13962                 error "caught a recursive fault"
13963         fi
13964         $LCTL set_param fail_loc=0
13965         true
13966 }
13967 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13968
13969 # it would be good to share it with obdfilter-survey/iokit-libecho code
13970 setup_obdecho_osc () {
13971         local rc=0
13972         local ost_nid=$1
13973         local obdfilter_name=$2
13974         echo "Creating new osc for $obdfilter_name on $ost_nid"
13975         # make sure we can find loopback nid
13976         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13977
13978         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13979                            ${obdfilter_name}_osc_UUID || rc=2; }
13980         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13981                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13982         return $rc
13983 }
13984
13985 cleanup_obdecho_osc () {
13986         local obdfilter_name=$1
13987         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
13988         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
13989         return 0
13990 }
13991
13992 obdecho_test() {
13993         local OBD=$1
13994         local node=$2
13995         local pages=${3:-64}
13996         local rc=0
13997         local id
13998
13999         local count=10
14000         local obd_size=$(get_obd_size $node $OBD)
14001         local page_size=$(get_page_size $node)
14002         if [[ -n "$obd_size" ]]; then
14003                 local new_count=$((obd_size / (pages * page_size / 1024)))
14004                 [[ $new_count -ge $count ]] || count=$new_count
14005         fi
14006
14007         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14008         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14009                            rc=2; }
14010         if [ $rc -eq 0 ]; then
14011             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14012             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14013         fi
14014         echo "New object id is $id"
14015         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14016                            rc=4; }
14017         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14018                            "test_brw $count w v $pages $id" || rc=4; }
14019         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14020                            rc=4; }
14021         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14022                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14023         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14024                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14025         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14026         return $rc
14027 }
14028
14029 test_180a() {
14030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14031
14032         if ! module_loaded obdecho; then
14033                 load_module obdecho/obdecho &&
14034                         stack_trap "rmmod obdecho" EXIT ||
14035                         error "unable to load obdecho on client"
14036         fi
14037
14038         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14039         local host=$($LCTL get_param -n osc.$osc.import |
14040                      awk '/current_connection:/ { print $2 }' )
14041         local target=$($LCTL get_param -n osc.$osc.import |
14042                        awk '/target:/ { print $2 }' )
14043         target=${target%_UUID}
14044
14045         if [ -n "$target" ]; then
14046                 setup_obdecho_osc $host $target &&
14047                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14048                         { error "obdecho setup failed with $?"; return; }
14049
14050                 obdecho_test ${target}_osc client ||
14051                         error "obdecho_test failed on ${target}_osc"
14052         else
14053                 $LCTL get_param osc.$osc.import
14054                 error "there is no osc.$osc.import target"
14055         fi
14056 }
14057 run_test 180a "test obdecho on osc"
14058
14059 test_180b() {
14060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14061         remote_ost_nodsh && skip "remote OST with nodsh"
14062
14063         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14064                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14065                 error "failed to load module obdecho"
14066
14067         local target=$(do_facet ost1 $LCTL dl |
14068                        awk '/obdfilter/ { print $4; exit; }')
14069
14070         if [ -n "$target" ]; then
14071                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14072         else
14073                 do_facet ost1 $LCTL dl
14074                 error "there is no obdfilter target on ost1"
14075         fi
14076 }
14077 run_test 180b "test obdecho directly on obdfilter"
14078
14079 test_180c() { # LU-2598
14080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14081         remote_ost_nodsh && skip "remote OST with nodsh"
14082         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14083                 skip "Need MDS version at least 2.4.0"
14084
14085         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14086                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14087                 error "failed to load module obdecho"
14088
14089         local target=$(do_facet ost1 $LCTL dl |
14090                        awk '/obdfilter/ { print $4; exit; }')
14091
14092         if [ -n "$target" ]; then
14093                 local pages=16384 # 64MB bulk I/O RPC size
14094
14095                 obdecho_test "$target" ost1 "$pages" ||
14096                         error "obdecho_test with pages=$pages failed with $?"
14097         else
14098                 do_facet ost1 $LCTL dl
14099                 error "there is no obdfilter target on ost1"
14100         fi
14101 }
14102 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14103
14104 test_181() { # bug 22177
14105         test_mkdir $DIR/$tdir
14106         # create enough files to index the directory
14107         createmany -o $DIR/$tdir/foobar 4000
14108         # print attributes for debug purpose
14109         lsattr -d .
14110         # open dir
14111         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14112         MULTIPID=$!
14113         # remove the files & current working dir
14114         unlinkmany $DIR/$tdir/foobar 4000
14115         rmdir $DIR/$tdir
14116         kill -USR1 $MULTIPID
14117         wait $MULTIPID
14118         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14119         return 0
14120 }
14121 run_test 181 "Test open-unlinked dir ========================"
14122
14123 test_182() {
14124         local fcount=1000
14125         local tcount=10
14126
14127         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14128
14129         $LCTL set_param mdc.*.rpc_stats=clear
14130
14131         for (( i = 0; i < $tcount; i++ )) ; do
14132                 mkdir $DIR/$tdir/$i
14133         done
14134
14135         for (( i = 0; i < $tcount; i++ )) ; do
14136                 createmany -o $DIR/$tdir/$i/f- $fcount &
14137         done
14138         wait
14139
14140         for (( i = 0; i < $tcount; i++ )) ; do
14141                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14142         done
14143         wait
14144
14145         $LCTL get_param mdc.*.rpc_stats
14146
14147         rm -rf $DIR/$tdir
14148 }
14149 run_test 182 "Test parallel modify metadata operations ================"
14150
14151 test_183() { # LU-2275
14152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14153         remote_mds_nodsh && skip "remote MDS with nodsh"
14154         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14155                 skip "Need MDS version at least 2.3.56"
14156
14157         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14158         echo aaa > $DIR/$tdir/$tfile
14159
14160 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14161         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14162
14163         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14164         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14165
14166         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14167
14168         # Flush negative dentry cache
14169         touch $DIR/$tdir/$tfile
14170
14171         # We are not checking for any leaked references here, they'll
14172         # become evident next time we do cleanup with module unload.
14173         rm -rf $DIR/$tdir
14174 }
14175 run_test 183 "No crash or request leak in case of strange dispositions ========"
14176
14177 # test suite 184 is for LU-2016, LU-2017
14178 test_184a() {
14179         check_swap_layouts_support
14180
14181         dir0=$DIR/$tdir/$testnum
14182         test_mkdir -p -c1 $dir0
14183         ref1=/etc/passwd
14184         ref2=/etc/group
14185         file1=$dir0/f1
14186         file2=$dir0/f2
14187         $LFS setstripe -c1 $file1
14188         cp $ref1 $file1
14189         $LFS setstripe -c2 $file2
14190         cp $ref2 $file2
14191         gen1=$($LFS getstripe -g $file1)
14192         gen2=$($LFS getstripe -g $file2)
14193
14194         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14195         gen=$($LFS getstripe -g $file1)
14196         [[ $gen1 != $gen ]] ||
14197                 "Layout generation on $file1 does not change"
14198         gen=$($LFS getstripe -g $file2)
14199         [[ $gen2 != $gen ]] ||
14200                 "Layout generation on $file2 does not change"
14201
14202         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14203         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14204
14205         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14206 }
14207 run_test 184a "Basic layout swap"
14208
14209 test_184b() {
14210         check_swap_layouts_support
14211
14212         dir0=$DIR/$tdir/$testnum
14213         mkdir -p $dir0 || error "creating dir $dir0"
14214         file1=$dir0/f1
14215         file2=$dir0/f2
14216         file3=$dir0/f3
14217         dir1=$dir0/d1
14218         dir2=$dir0/d2
14219         mkdir $dir1 $dir2
14220         $LFS setstripe -c1 $file1
14221         $LFS setstripe -c2 $file2
14222         $LFS setstripe -c1 $file3
14223         chown $RUNAS_ID $file3
14224         gen1=$($LFS getstripe -g $file1)
14225         gen2=$($LFS getstripe -g $file2)
14226
14227         $LFS swap_layouts $dir1 $dir2 &&
14228                 error "swap of directories layouts should fail"
14229         $LFS swap_layouts $dir1 $file1 &&
14230                 error "swap of directory and file layouts should fail"
14231         $RUNAS $LFS swap_layouts $file1 $file2 &&
14232                 error "swap of file we cannot write should fail"
14233         $LFS swap_layouts $file1 $file3 &&
14234                 error "swap of file with different owner should fail"
14235         /bin/true # to clear error code
14236 }
14237 run_test 184b "Forbidden layout swap (will generate errors)"
14238
14239 test_184c() {
14240         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14241         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14242         check_swap_layouts_support
14243
14244         local dir0=$DIR/$tdir/$testnum
14245         mkdir -p $dir0 || error "creating dir $dir0"
14246
14247         local ref1=$dir0/ref1
14248         local ref2=$dir0/ref2
14249         local file1=$dir0/file1
14250         local file2=$dir0/file2
14251         # create a file large enough for the concurrent test
14252         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14253         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14254         echo "ref file size: ref1($(stat -c %s $ref1))," \
14255              "ref2($(stat -c %s $ref2))"
14256
14257         cp $ref2 $file2
14258         dd if=$ref1 of=$file1 bs=16k &
14259         local DD_PID=$!
14260
14261         # Make sure dd starts to copy file
14262         while [ ! -f $file1 ]; do sleep 0.1; done
14263
14264         $LFS swap_layouts $file1 $file2
14265         local rc=$?
14266         wait $DD_PID
14267         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14268         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14269
14270         # how many bytes copied before swapping layout
14271         local copied=$(stat -c %s $file2)
14272         local remaining=$(stat -c %s $ref1)
14273         remaining=$((remaining - copied))
14274         echo "Copied $copied bytes before swapping layout..."
14275
14276         cmp -n $copied $file1 $ref2 | grep differ &&
14277                 error "Content mismatch [0, $copied) of ref2 and file1"
14278         cmp -n $copied $file2 $ref1 ||
14279                 error "Content mismatch [0, $copied) of ref1 and file2"
14280         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14281                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14282
14283         # clean up
14284         rm -f $ref1 $ref2 $file1 $file2
14285 }
14286 run_test 184c "Concurrent write and layout swap"
14287
14288 test_184d() {
14289         check_swap_layouts_support
14290         [ -z "$(which getfattr 2>/dev/null)" ] &&
14291                 skip_env "no getfattr command"
14292
14293         local file1=$DIR/$tdir/$tfile-1
14294         local file2=$DIR/$tdir/$tfile-2
14295         local file3=$DIR/$tdir/$tfile-3
14296         local lovea1
14297         local lovea2
14298
14299         mkdir -p $DIR/$tdir
14300         touch $file1 || error "create $file1 failed"
14301         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14302                 error "create $file2 failed"
14303         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14304                 error "create $file3 failed"
14305         lovea1=$(get_layout_param $file1)
14306
14307         $LFS swap_layouts $file2 $file3 ||
14308                 error "swap $file2 $file3 layouts failed"
14309         $LFS swap_layouts $file1 $file2 ||
14310                 error "swap $file1 $file2 layouts failed"
14311
14312         lovea2=$(get_layout_param $file2)
14313         echo "$lovea1"
14314         echo "$lovea2"
14315         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14316
14317         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14318         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14319 }
14320 run_test 184d "allow stripeless layouts swap"
14321
14322 test_184e() {
14323         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14324                 skip "Need MDS version at least 2.6.94"
14325         check_swap_layouts_support
14326         [ -z "$(which getfattr 2>/dev/null)" ] &&
14327                 skip_env "no getfattr command"
14328
14329         local file1=$DIR/$tdir/$tfile-1
14330         local file2=$DIR/$tdir/$tfile-2
14331         local file3=$DIR/$tdir/$tfile-3
14332         local lovea
14333
14334         mkdir -p $DIR/$tdir
14335         touch $file1 || error "create $file1 failed"
14336         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14337                 error "create $file2 failed"
14338         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14339                 error "create $file3 failed"
14340
14341         $LFS swap_layouts $file1 $file2 ||
14342                 error "swap $file1 $file2 layouts failed"
14343
14344         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14345         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
14346
14347         echo 123 > $file1 || error "Should be able to write into $file1"
14348
14349         $LFS swap_layouts $file1 $file3 ||
14350                 error "swap $file1 $file3 layouts failed"
14351
14352         echo 123 > $file1 || error "Should be able to write into $file1"
14353
14354         rm -rf $file1 $file2 $file3
14355 }
14356 run_test 184e "Recreate layout after stripeless layout swaps"
14357
14358 test_184f() {
14359         # Create a file with name longer than sizeof(struct stat) ==
14360         # 144 to see if we can get chars from the file name to appear
14361         # in the returned striping. Note that 'f' == 0x66.
14362         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
14363
14364         mkdir -p $DIR/$tdir
14365         mcreate $DIR/$tdir/$file
14366         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
14367                 error "IOC_MDC_GETFILEINFO returned garbage striping"
14368         fi
14369 }
14370 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
14371
14372 test_185() { # LU-2441
14373         # LU-3553 - no volatile file support in old servers
14374         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
14375                 skip "Need MDS version at least 2.3.60"
14376
14377         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14378         touch $DIR/$tdir/spoo
14379         local mtime1=$(stat -c "%Y" $DIR/$tdir)
14380         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
14381                 error "cannot create/write a volatile file"
14382         [ "$FILESET" == "" ] &&
14383         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
14384                 error "FID is still valid after close"
14385
14386         multiop_bg_pause $DIR/$tdir vVw4096_c
14387         local multi_pid=$!
14388
14389         local OLD_IFS=$IFS
14390         IFS=":"
14391         local fidv=($fid)
14392         IFS=$OLD_IFS
14393         # assume that the next FID for this client is sequential, since stdout
14394         # is unfortunately eaten by multiop_bg_pause
14395         local n=$((${fidv[1]} + 1))
14396         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
14397         if [ "$FILESET" == "" ]; then
14398                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
14399                         error "FID is missing before close"
14400         fi
14401         kill -USR1 $multi_pid
14402         # 1 second delay, so if mtime change we will see it
14403         sleep 1
14404         local mtime2=$(stat -c "%Y" $DIR/$tdir)
14405         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
14406 }
14407 run_test 185 "Volatile file support"
14408
14409 test_187a() {
14410         remote_mds_nodsh && skip "remote MDS with nodsh"
14411         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14412                 skip "Need MDS version at least 2.3.0"
14413
14414         local dir0=$DIR/$tdir/$testnum
14415         mkdir -p $dir0 || error "creating dir $dir0"
14416
14417         local file=$dir0/file1
14418         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
14419         local dv1=$($LFS data_version $file)
14420         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
14421         local dv2=$($LFS data_version $file)
14422         [[ $dv1 != $dv2 ]] ||
14423                 error "data version did not change on write $dv1 == $dv2"
14424
14425         # clean up
14426         rm -f $file1
14427 }
14428 run_test 187a "Test data version change"
14429
14430 test_187b() {
14431         remote_mds_nodsh && skip "remote MDS with nodsh"
14432         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14433                 skip "Need MDS version at least 2.3.0"
14434
14435         local dir0=$DIR/$tdir/$testnum
14436         mkdir -p $dir0 || error "creating dir $dir0"
14437
14438         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
14439         [[ ${DV[0]} != ${DV[1]} ]] ||
14440                 error "data version did not change on write"\
14441                       " ${DV[0]} == ${DV[1]}"
14442
14443         # clean up
14444         rm -f $file1
14445 }
14446 run_test 187b "Test data version change on volatile file"
14447
14448 test_200() {
14449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14450         remote_mgs_nodsh && skip "remote MGS with nodsh"
14451         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14452
14453         local POOL=${POOL:-cea1}
14454         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14455         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14456         # Pool OST targets
14457         local first_ost=0
14458         local last_ost=$(($OSTCOUNT - 1))
14459         local ost_step=2
14460         local ost_list=$(seq $first_ost $ost_step $last_ost)
14461         local ost_range="$first_ost $last_ost $ost_step"
14462         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14463         local file_dir=$POOL_ROOT/file_tst
14464         local subdir=$test_path/subdir
14465         local rc=0
14466
14467         if ! combined_mgs_mds ; then
14468                 mount_mgs_client
14469         fi
14470
14471         while : ; do
14472                 # former test_200a test_200b
14473                 pool_add $POOL                          || { rc=$? ; break; }
14474                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14475                 # former test_200c test_200d
14476                 mkdir -p $test_path
14477                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14478                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14479                 mkdir -p $subdir
14480                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14481                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14482                                                         || { rc=$? ; break; }
14483                 # former test_200e test_200f
14484                 local files=$((OSTCOUNT*3))
14485                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14486                                                         || { rc=$? ; break; }
14487                 pool_create_files $POOL $file_dir $files "$ost_list" \
14488                                                         || { rc=$? ; break; }
14489                 # former test_200g test_200h
14490                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14491                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14492
14493                 # former test_201a test_201b test_201c
14494                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14495
14496                 local f=$test_path/$tfile
14497                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14498                 pool_remove $POOL $f                    || { rc=$? ; break; }
14499                 break
14500         done
14501
14502         destroy_test_pools
14503
14504         if ! combined_mgs_mds ; then
14505                 umount_mgs_client
14506         fi
14507         return $rc
14508 }
14509 run_test 200 "OST pools"
14510
14511 # usage: default_attr <count | size | offset>
14512 default_attr() {
14513         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14514 }
14515
14516 # usage: check_default_stripe_attr
14517 check_default_stripe_attr() {
14518         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14519         case $1 in
14520         --stripe-count|-c)
14521                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14522         --stripe-size|-S)
14523                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14524         --stripe-index|-i)
14525                 EXPECTED=-1;;
14526         *)
14527                 error "unknown getstripe attr '$1'"
14528         esac
14529
14530         [ $ACTUAL == $EXPECTED ] ||
14531                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14532 }
14533
14534 test_204a() {
14535         test_mkdir $DIR/$tdir
14536         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14537
14538         check_default_stripe_attr --stripe-count
14539         check_default_stripe_attr --stripe-size
14540         check_default_stripe_attr --stripe-index
14541 }
14542 run_test 204a "Print default stripe attributes"
14543
14544 test_204b() {
14545         test_mkdir $DIR/$tdir
14546         $LFS setstripe --stripe-count 1 $DIR/$tdir
14547
14548         check_default_stripe_attr --stripe-size
14549         check_default_stripe_attr --stripe-index
14550 }
14551 run_test 204b "Print default stripe size and offset"
14552
14553 test_204c() {
14554         test_mkdir $DIR/$tdir
14555         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14556
14557         check_default_stripe_attr --stripe-count
14558         check_default_stripe_attr --stripe-index
14559 }
14560 run_test 204c "Print default stripe count and offset"
14561
14562 test_204d() {
14563         test_mkdir $DIR/$tdir
14564         $LFS setstripe --stripe-index 0 $DIR/$tdir
14565
14566         check_default_stripe_attr --stripe-count
14567         check_default_stripe_attr --stripe-size
14568 }
14569 run_test 204d "Print default stripe count and size"
14570
14571 test_204e() {
14572         test_mkdir $DIR/$tdir
14573         $LFS setstripe -d $DIR/$tdir
14574
14575         check_default_stripe_attr --stripe-count --raw
14576         check_default_stripe_attr --stripe-size --raw
14577         check_default_stripe_attr --stripe-index --raw
14578 }
14579 run_test 204e "Print raw stripe attributes"
14580
14581 test_204f() {
14582         test_mkdir $DIR/$tdir
14583         $LFS setstripe --stripe-count 1 $DIR/$tdir
14584
14585         check_default_stripe_attr --stripe-size --raw
14586         check_default_stripe_attr --stripe-index --raw
14587 }
14588 run_test 204f "Print raw stripe size and offset"
14589
14590 test_204g() {
14591         test_mkdir $DIR/$tdir
14592         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14593
14594         check_default_stripe_attr --stripe-count --raw
14595         check_default_stripe_attr --stripe-index --raw
14596 }
14597 run_test 204g "Print raw stripe count and offset"
14598
14599 test_204h() {
14600         test_mkdir $DIR/$tdir
14601         $LFS setstripe --stripe-index 0 $DIR/$tdir
14602
14603         check_default_stripe_attr --stripe-count --raw
14604         check_default_stripe_attr --stripe-size --raw
14605 }
14606 run_test 204h "Print raw stripe count and size"
14607
14608 # Figure out which job scheduler is being used, if any,
14609 # or use a fake one
14610 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14611         JOBENV=SLURM_JOB_ID
14612 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14613         JOBENV=LSB_JOBID
14614 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14615         JOBENV=PBS_JOBID
14616 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14617         JOBENV=LOADL_STEP_ID
14618 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14619         JOBENV=JOB_ID
14620 else
14621         $LCTL list_param jobid_name > /dev/null 2>&1
14622         if [ $? -eq 0 ]; then
14623                 JOBENV=nodelocal
14624         else
14625                 JOBENV=FAKE_JOBID
14626         fi
14627 fi
14628 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14629
14630 verify_jobstats() {
14631         local cmd=($1)
14632         shift
14633         local facets="$@"
14634
14635 # we don't really need to clear the stats for this test to work, since each
14636 # command has a unique jobid, but it makes debugging easier if needed.
14637 #       for facet in $facets; do
14638 #               local dev=$(convert_facet2label $facet)
14639 #               # clear old jobstats
14640 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14641 #       done
14642
14643         # use a new JobID for each test, or we might see an old one
14644         [ "$JOBENV" = "FAKE_JOBID" ] &&
14645                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14646
14647         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14648
14649         [ "$JOBENV" = "nodelocal" ] && {
14650                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14651                 $LCTL set_param jobid_name=$FAKE_JOBID
14652                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14653         }
14654
14655         log "Test: ${cmd[*]}"
14656         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14657
14658         if [ $JOBENV = "FAKE_JOBID" ]; then
14659                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14660         else
14661                 ${cmd[*]}
14662         fi
14663
14664         # all files are created on OST0000
14665         for facet in $facets; do
14666                 local stats="*.$(convert_facet2label $facet).job_stats"
14667
14668                 # strip out libtool wrappers for in-tree executables
14669                 if [ $(do_facet $facet lctl get_param $stats |
14670                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14671                         do_facet $facet lctl get_param $stats
14672                         error "No jobstats for $JOBVAL found on $facet::$stats"
14673                 fi
14674         done
14675 }
14676
14677 jobstats_set() {
14678         local new_jobenv=$1
14679
14680         set_persistent_param_and_check client "jobid_var" \
14681                 "$FSNAME.sys.jobid_var" $new_jobenv
14682 }
14683
14684 test_205() { # Job stats
14685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14686         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14687                 skip "Need MDS version with at least 2.7.1"
14688         remote_mgs_nodsh && skip "remote MGS with nodsh"
14689         remote_mds_nodsh && skip "remote MDS with nodsh"
14690         remote_ost_nodsh && skip "remote OST with nodsh"
14691         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14692                 skip "Server doesn't support jobstats"
14693         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14694
14695         local old_jobenv=$($LCTL get_param -n jobid_var)
14696         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14697
14698         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14699                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14700         else
14701                 stack_trap "do_facet mgs $PERM_CMD \
14702                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14703         fi
14704         changelog_register
14705
14706         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14707                                 mdt.*.job_cleanup_interval | head -n 1)
14708         local new_interval=5
14709         do_facet $SINGLEMDS \
14710                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14711         stack_trap "do_facet $SINGLEMDS \
14712                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14713         local start=$SECONDS
14714
14715         local cmd
14716         # mkdir
14717         cmd="mkdir $DIR/$tdir"
14718         verify_jobstats "$cmd" "$SINGLEMDS"
14719         # rmdir
14720         cmd="rmdir $DIR/$tdir"
14721         verify_jobstats "$cmd" "$SINGLEMDS"
14722         # mkdir on secondary MDT
14723         if [ $MDSCOUNT -gt 1 ]; then
14724                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14725                 verify_jobstats "$cmd" "mds2"
14726         fi
14727         # mknod
14728         cmd="mknod $DIR/$tfile c 1 3"
14729         verify_jobstats "$cmd" "$SINGLEMDS"
14730         # unlink
14731         cmd="rm -f $DIR/$tfile"
14732         verify_jobstats "$cmd" "$SINGLEMDS"
14733         # create all files on OST0000 so verify_jobstats can find OST stats
14734         # open & close
14735         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14736         verify_jobstats "$cmd" "$SINGLEMDS"
14737         # setattr
14738         cmd="touch $DIR/$tfile"
14739         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14740         # write
14741         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14742         verify_jobstats "$cmd" "ost1"
14743         # read
14744         cancel_lru_locks osc
14745         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14746         verify_jobstats "$cmd" "ost1"
14747         # truncate
14748         cmd="$TRUNCATE $DIR/$tfile 0"
14749         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14750         # rename
14751         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14752         verify_jobstats "$cmd" "$SINGLEMDS"
14753         # jobstats expiry - sleep until old stats should be expired
14754         local left=$((new_interval + 5 - (SECONDS - start)))
14755         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14756                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14757                         "0" $left
14758         cmd="mkdir $DIR/$tdir.expire"
14759         verify_jobstats "$cmd" "$SINGLEMDS"
14760         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14761             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14762
14763         # Ensure that jobid are present in changelog (if supported by MDS)
14764         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14765                 changelog_dump | tail -10
14766                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14767                 [ $jobids -eq 9 ] ||
14768                         error "Wrong changelog jobid count $jobids != 9"
14769
14770                 # LU-5862
14771                 JOBENV="disable"
14772                 jobstats_set $JOBENV
14773                 touch $DIR/$tfile
14774                 changelog_dump | grep $tfile
14775                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14776                 [ $jobids -eq 0 ] ||
14777                         error "Unexpected jobids when jobid_var=$JOBENV"
14778         fi
14779
14780         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14781         JOBENV="JOBCOMPLEX"
14782         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14783
14784         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14785 }
14786 run_test 205 "Verify job stats"
14787
14788 # LU-1480, LU-1773 and LU-1657
14789 test_206() {
14790         mkdir -p $DIR/$tdir
14791         $LFS setstripe -c -1 $DIR/$tdir
14792 #define OBD_FAIL_LOV_INIT 0x1403
14793         $LCTL set_param fail_loc=0xa0001403
14794         $LCTL set_param fail_val=1
14795         touch $DIR/$tdir/$tfile || true
14796 }
14797 run_test 206 "fail lov_init_raid0() doesn't lbug"
14798
14799 test_207a() {
14800         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14801         local fsz=`stat -c %s $DIR/$tfile`
14802         cancel_lru_locks mdc
14803
14804         # do not return layout in getattr intent
14805 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14806         $LCTL set_param fail_loc=0x170
14807         local sz=`stat -c %s $DIR/$tfile`
14808
14809         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14810
14811         rm -rf $DIR/$tfile
14812 }
14813 run_test 207a "can refresh layout at glimpse"
14814
14815 test_207b() {
14816         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14817         local cksum=`md5sum $DIR/$tfile`
14818         local fsz=`stat -c %s $DIR/$tfile`
14819         cancel_lru_locks mdc
14820         cancel_lru_locks osc
14821
14822         # do not return layout in getattr intent
14823 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14824         $LCTL set_param fail_loc=0x171
14825
14826         # it will refresh layout after the file is opened but before read issues
14827         echo checksum is "$cksum"
14828         echo "$cksum" |md5sum -c --quiet || error "file differs"
14829
14830         rm -rf $DIR/$tfile
14831 }
14832 run_test 207b "can refresh layout at open"
14833
14834 test_208() {
14835         # FIXME: in this test suite, only RD lease is used. This is okay
14836         # for now as only exclusive open is supported. After generic lease
14837         # is done, this test suite should be revised. - Jinshan
14838
14839         remote_mds_nodsh && skip "remote MDS with nodsh"
14840         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14841                 skip "Need MDS version at least 2.4.52"
14842
14843         echo "==== test 1: verify get lease work"
14844         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14845
14846         echo "==== test 2: verify lease can be broken by upcoming open"
14847         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14848         local PID=$!
14849         sleep 1
14850
14851         $MULTIOP $DIR/$tfile oO_RDONLY:c
14852         kill -USR1 $PID && wait $PID || error "break lease error"
14853
14854         echo "==== test 3: verify lease can't be granted if an open already exists"
14855         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14856         local PID=$!
14857         sleep 1
14858
14859         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14860         kill -USR1 $PID && wait $PID || error "open file error"
14861
14862         echo "==== test 4: lease can sustain over recovery"
14863         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14864         PID=$!
14865         sleep 1
14866
14867         fail mds1
14868
14869         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14870
14871         echo "==== test 5: lease broken can't be regained by replay"
14872         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14873         PID=$!
14874         sleep 1
14875
14876         # open file to break lease and then recovery
14877         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14878         fail mds1
14879
14880         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14881
14882         rm -f $DIR/$tfile
14883 }
14884 run_test 208 "Exclusive open"
14885
14886 test_209() {
14887         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14888                 skip_env "must have disp_stripe"
14889
14890         touch $DIR/$tfile
14891         sync; sleep 5; sync;
14892
14893         echo 3 > /proc/sys/vm/drop_caches
14894         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14895
14896         # open/close 500 times
14897         for i in $(seq 500); do
14898                 cat $DIR/$tfile
14899         done
14900
14901         echo 3 > /proc/sys/vm/drop_caches
14902         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14903
14904         echo "before: $req_before, after: $req_after"
14905         [ $((req_after - req_before)) -ge 300 ] &&
14906                 error "open/close requests are not freed"
14907         return 0
14908 }
14909 run_test 209 "read-only open/close requests should be freed promptly"
14910
14911 test_212() {
14912         size=`date +%s`
14913         size=$((size % 8192 + 1))
14914         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14915         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14916         rm -f $DIR/f212 $DIR/f212.xyz
14917 }
14918 run_test 212 "Sendfile test ============================================"
14919
14920 test_213() {
14921         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14922         cancel_lru_locks osc
14923         lctl set_param fail_loc=0x8000040f
14924         # generate a read lock
14925         cat $DIR/$tfile > /dev/null
14926         # write to the file, it will try to cancel the above read lock.
14927         cat /etc/hosts >> $DIR/$tfile
14928 }
14929 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14930
14931 test_214() { # for bug 20133
14932         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14933         for (( i=0; i < 340; i++ )) ; do
14934                 touch $DIR/$tdir/d214c/a$i
14935         done
14936
14937         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14938         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14939         ls $DIR/d214c || error "ls $DIR/d214c failed"
14940         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14941         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14942 }
14943 run_test 214 "hash-indexed directory test - bug 20133"
14944
14945 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14946 create_lnet_proc_files() {
14947         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14948 }
14949
14950 # counterpart of create_lnet_proc_files
14951 remove_lnet_proc_files() {
14952         rm -f $TMP/lnet_$1.sys
14953 }
14954
14955 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14956 # 3rd arg as regexp for body
14957 check_lnet_proc_stats() {
14958         local l=$(cat "$TMP/lnet_$1" |wc -l)
14959         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14960
14961         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14962 }
14963
14964 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14965 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14966 # optional and can be regexp for 2nd line (lnet.routes case)
14967 check_lnet_proc_entry() {
14968         local blp=2          # blp stands for 'position of 1st line of body'
14969         [ -z "$5" ] || blp=3 # lnet.routes case
14970
14971         local l=$(cat "$TMP/lnet_$1" |wc -l)
14972         # subtracting one from $blp because the body can be empty
14973         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14974
14975         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14976                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14977
14978         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14979                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14980
14981         # bail out if any unexpected line happened
14982         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
14983         [ "$?" != 0 ] || error "$2 misformatted"
14984 }
14985
14986 test_215() { # for bugs 18102, 21079, 21517
14987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14988
14989         local N='(0|[1-9][0-9]*)'       # non-negative numeric
14990         local P='[1-9][0-9]*'           # positive numeric
14991         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
14992         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
14993         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
14994         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
14995
14996         local L1 # regexp for 1st line
14997         local L2 # regexp for 2nd line (optional)
14998         local BR # regexp for the rest (body)
14999
15000         # lnet.stats should look as 11 space-separated non-negative numerics
15001         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15002         create_lnet_proc_files "stats"
15003         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15004         remove_lnet_proc_files "stats"
15005
15006         # lnet.routes should look like this:
15007         # Routing disabled/enabled
15008         # net hops priority state router
15009         # where net is a string like tcp0, hops > 0, priority >= 0,
15010         # state is up/down,
15011         # router is a string like 192.168.1.1@tcp2
15012         L1="^Routing (disabled|enabled)$"
15013         L2="^net +hops +priority +state +router$"
15014         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15015         create_lnet_proc_files "routes"
15016         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15017         remove_lnet_proc_files "routes"
15018
15019         # lnet.routers should look like this:
15020         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15021         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15022         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15023         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15024         L1="^ref +rtr_ref +alive +router$"
15025         BR="^$P +$P +(up|down) +$NID$"
15026         create_lnet_proc_files "routers"
15027         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15028         remove_lnet_proc_files "routers"
15029
15030         # lnet.peers should look like this:
15031         # nid refs state last max rtr min tx min queue
15032         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15033         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15034         # numeric (0 or >0 or <0), queue >= 0.
15035         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15036         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15037         create_lnet_proc_files "peers"
15038         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15039         remove_lnet_proc_files "peers"
15040
15041         # lnet.buffers  should look like this:
15042         # pages count credits min
15043         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15044         L1="^pages +count +credits +min$"
15045         BR="^ +$N +$N +$I +$I$"
15046         create_lnet_proc_files "buffers"
15047         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15048         remove_lnet_proc_files "buffers"
15049
15050         # lnet.nis should look like this:
15051         # nid status alive refs peer rtr max tx min
15052         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15053         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15054         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15055         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15056         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15057         create_lnet_proc_files "nis"
15058         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15059         remove_lnet_proc_files "nis"
15060
15061         # can we successfully write to lnet.stats?
15062         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15063 }
15064 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15065
15066 test_216() { # bug 20317
15067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15068         remote_ost_nodsh && skip "remote OST with nodsh"
15069
15070         local node
15071         local facets=$(get_facets OST)
15072         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15073
15074         save_lustre_params client "osc.*.contention_seconds" > $p
15075         save_lustre_params $facets \
15076                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15077         save_lustre_params $facets \
15078                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15079         save_lustre_params $facets \
15080                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15081         clear_stats osc.*.osc_stats
15082
15083         # agressive lockless i/o settings
15084         do_nodes $(comma_list $(osts_nodes)) \
15085                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15086                         ldlm.namespaces.filter-*.contended_locks=0 \
15087                         ldlm.namespaces.filter-*.contention_seconds=60"
15088         lctl set_param -n osc.*.contention_seconds=60
15089
15090         $DIRECTIO write $DIR/$tfile 0 10 4096
15091         $CHECKSTAT -s 40960 $DIR/$tfile
15092
15093         # disable lockless i/o
15094         do_nodes $(comma_list $(osts_nodes)) \
15095                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15096                         ldlm.namespaces.filter-*.contended_locks=32 \
15097                         ldlm.namespaces.filter-*.contention_seconds=0"
15098         lctl set_param -n osc.*.contention_seconds=0
15099         clear_stats osc.*.osc_stats
15100
15101         dd if=/dev/zero of=$DIR/$tfile count=0
15102         $CHECKSTAT -s 0 $DIR/$tfile
15103
15104         restore_lustre_params <$p
15105         rm -f $p
15106         rm $DIR/$tfile
15107 }
15108 run_test 216 "check lockless direct write updates file size and kms correctly"
15109
15110 test_217() { # bug 22430
15111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15112
15113         local node
15114         local nid
15115
15116         for node in $(nodes_list); do
15117                 nid=$(host_nids_address $node $NETTYPE)
15118                 if [[ $nid = *-* ]] ; then
15119                         echo "lctl ping $(h2nettype $nid)"
15120                         lctl ping $(h2nettype $nid)
15121                 else
15122                         echo "skipping $node (no hyphen detected)"
15123                 fi
15124         done
15125 }
15126 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15127
15128 test_218() {
15129        # do directio so as not to populate the page cache
15130        log "creating a 10 Mb file"
15131        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15132        log "starting reads"
15133        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15134        log "truncating the file"
15135        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15136        log "killing dd"
15137        kill %+ || true # reads might have finished
15138        echo "wait until dd is finished"
15139        wait
15140        log "removing the temporary file"
15141        rm -rf $DIR/$tfile || error "tmp file removal failed"
15142 }
15143 run_test 218 "parallel read and truncate should not deadlock"
15144
15145 test_219() {
15146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15147
15148         # write one partial page
15149         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15150         # set no grant so vvp_io_commit_write will do sync write
15151         $LCTL set_param fail_loc=0x411
15152         # write a full page at the end of file
15153         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15154
15155         $LCTL set_param fail_loc=0
15156         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15157         $LCTL set_param fail_loc=0x411
15158         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15159
15160         # LU-4201
15161         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15162         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15163 }
15164 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15165
15166 test_220() { #LU-325
15167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15168         remote_ost_nodsh && skip "remote OST with nodsh"
15169         remote_mds_nodsh && skip "remote MDS with nodsh"
15170         remote_mgs_nodsh && skip "remote MGS with nodsh"
15171
15172         local OSTIDX=0
15173
15174         # create on MDT0000 so the last_id and next_id are correct
15175         mkdir $DIR/$tdir
15176         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15177         OST=${OST%_UUID}
15178
15179         # on the mdt's osc
15180         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15181         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15182                         osp.$mdtosc_proc1.prealloc_last_id)
15183         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15184                         osp.$mdtosc_proc1.prealloc_next_id)
15185
15186         $LFS df -i
15187
15188         if ! combined_mgs_mds ; then
15189                 mount_mgs_client
15190         fi
15191
15192         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15193         #define OBD_FAIL_OST_ENOINO              0x229
15194         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15195         create_pool $FSNAME.$TESTNAME || return 1
15196         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15197
15198         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15199
15200         MDSOBJS=$((last_id - next_id))
15201         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15202
15203         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15204         echo "OST still has $count kbytes free"
15205
15206         echo "create $MDSOBJS files @next_id..."
15207         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15208
15209         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15210                         osp.$mdtosc_proc1.prealloc_last_id)
15211         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15212                         osp.$mdtosc_proc1.prealloc_next_id)
15213
15214         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15215         $LFS df -i
15216
15217         echo "cleanup..."
15218
15219         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15220         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15221
15222         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15223                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15224         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15225                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15226         echo "unlink $MDSOBJS files @$next_id..."
15227         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15228
15229         if ! combined_mgs_mds ; then
15230                 umount_mgs_client
15231         fi
15232 }
15233 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15234
15235 test_221() {
15236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15237
15238         dd if=`which date` of=$MOUNT/date oflag=sync
15239         chmod +x $MOUNT/date
15240
15241         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15242         $LCTL set_param fail_loc=0x80001401
15243
15244         $MOUNT/date > /dev/null
15245         rm -f $MOUNT/date
15246 }
15247 run_test 221 "make sure fault and truncate race to not cause OOM"
15248
15249 test_222a () {
15250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15251
15252         rm -rf $DIR/$tdir
15253         test_mkdir $DIR/$tdir
15254         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15255         createmany -o $DIR/$tdir/$tfile 10
15256         cancel_lru_locks mdc
15257         cancel_lru_locks osc
15258         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15259         $LCTL set_param fail_loc=0x31a
15260         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15261         $LCTL set_param fail_loc=0
15262         rm -r $DIR/$tdir
15263 }
15264 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15265
15266 test_222b () {
15267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15268
15269         rm -rf $DIR/$tdir
15270         test_mkdir $DIR/$tdir
15271         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15272         createmany -o $DIR/$tdir/$tfile 10
15273         cancel_lru_locks mdc
15274         cancel_lru_locks osc
15275         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15276         $LCTL set_param fail_loc=0x31a
15277         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15278         $LCTL set_param fail_loc=0
15279 }
15280 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15281
15282 test_223 () {
15283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15284
15285         rm -rf $DIR/$tdir
15286         test_mkdir $DIR/$tdir
15287         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15288         createmany -o $DIR/$tdir/$tfile 10
15289         cancel_lru_locks mdc
15290         cancel_lru_locks osc
15291         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15292         $LCTL set_param fail_loc=0x31b
15293         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15294         $LCTL set_param fail_loc=0
15295         rm -r $DIR/$tdir
15296 }
15297 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15298
15299 test_224a() { # LU-1039, MRP-303
15300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15301
15302         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15303         $LCTL set_param fail_loc=0x508
15304         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15305         $LCTL set_param fail_loc=0
15306         df $DIR
15307 }
15308 run_test 224a "Don't panic on bulk IO failure"
15309
15310 test_224b() { # LU-1039, MRP-303
15311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15312
15313         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
15314         cancel_lru_locks osc
15315         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
15316         $LCTL set_param fail_loc=0x515
15317         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
15318         $LCTL set_param fail_loc=0
15319         df $DIR
15320 }
15321 run_test 224b "Don't panic on bulk IO failure"
15322
15323 test_224c() { # LU-6441
15324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15325         remote_mds_nodsh && skip "remote MDS with nodsh"
15326
15327         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15328         save_writethrough $p
15329         set_cache writethrough on
15330
15331         local pages_per_rpc=$($LCTL get_param \
15332                                 osc.*.max_pages_per_rpc)
15333         local at_max=$($LCTL get_param -n at_max)
15334         local timeout=$($LCTL get_param -n timeout)
15335         local test_at="at_max"
15336         local param_at="$FSNAME.sys.at_max"
15337         local test_timeout="timeout"
15338         local param_timeout="$FSNAME.sys.timeout"
15339
15340         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
15341
15342         set_persistent_param_and_check client "$test_at" "$param_at" 0
15343         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
15344
15345         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
15346         do_facet ost1 "$LCTL set_param fail_loc=0x520"
15347         $LFS setstripe -c 1 -i 0 $DIR/$tfile
15348         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
15349         sync
15350         do_facet ost1 "$LCTL set_param fail_loc=0"
15351
15352         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
15353         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
15354                 $timeout
15355
15356         $LCTL set_param -n $pages_per_rpc
15357         restore_lustre_params < $p
15358         rm -f $p
15359 }
15360 run_test 224c "Don't hang if one of md lost during large bulk RPC"
15361
15362 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
15363 test_225a () {
15364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15365         if [ -z ${MDSSURVEY} ]; then
15366                 skip_env "mds-survey not found"
15367         fi
15368         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15369                 skip "Need MDS version at least 2.2.51"
15370
15371         local mds=$(facet_host $SINGLEMDS)
15372         local target=$(do_nodes $mds 'lctl dl' |
15373                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15374
15375         local cmd1="file_count=1000 thrhi=4"
15376         local cmd2="dir_count=2 layer=mdd stripe_count=0"
15377         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15378         local cmd="$cmd1 $cmd2 $cmd3"
15379
15380         rm -f ${TMP}/mds_survey*
15381         echo + $cmd
15382         eval $cmd || error "mds-survey with zero-stripe failed"
15383         cat ${TMP}/mds_survey*
15384         rm -f ${TMP}/mds_survey*
15385 }
15386 run_test 225a "Metadata survey sanity with zero-stripe"
15387
15388 test_225b () {
15389         if [ -z ${MDSSURVEY} ]; then
15390                 skip_env "mds-survey not found"
15391         fi
15392         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15393                 skip "Need MDS version at least 2.2.51"
15394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15395         remote_mds_nodsh && skip "remote MDS with nodsh"
15396         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
15397                 skip_env "Need to mount OST to test"
15398         fi
15399
15400         local mds=$(facet_host $SINGLEMDS)
15401         local target=$(do_nodes $mds 'lctl dl' |
15402                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15403
15404         local cmd1="file_count=1000 thrhi=4"
15405         local cmd2="dir_count=2 layer=mdd stripe_count=1"
15406         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15407         local cmd="$cmd1 $cmd2 $cmd3"
15408
15409         rm -f ${TMP}/mds_survey*
15410         echo + $cmd
15411         eval $cmd || error "mds-survey with stripe_count failed"
15412         cat ${TMP}/mds_survey*
15413         rm -f ${TMP}/mds_survey*
15414 }
15415 run_test 225b "Metadata survey sanity with stripe_count = 1"
15416
15417 mcreate_path2fid () {
15418         local mode=$1
15419         local major=$2
15420         local minor=$3
15421         local name=$4
15422         local desc=$5
15423         local path=$DIR/$tdir/$name
15424         local fid
15425         local rc
15426         local fid_path
15427
15428         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
15429                 error "cannot create $desc"
15430
15431         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
15432         rc=$?
15433         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
15434
15435         fid_path=$($LFS fid2path $MOUNT $fid)
15436         rc=$?
15437         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
15438
15439         [ "$path" == "$fid_path" ] ||
15440                 error "fid2path returned $fid_path, expected $path"
15441
15442         echo "pass with $path and $fid"
15443 }
15444
15445 test_226a () {
15446         rm -rf $DIR/$tdir
15447         mkdir -p $DIR/$tdir
15448
15449         mcreate_path2fid 0010666 0 0 fifo "FIFO"
15450         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15451         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15452         mcreate_path2fid 0040666 0 0 dir "directory"
15453         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15454         mcreate_path2fid 0100666 0 0 file "regular file"
15455         mcreate_path2fid 0120666 0 0 link "symbolic link"
15456         mcreate_path2fid 0140666 0 0 sock "socket"
15457 }
15458 run_test 226a "call path2fid and fid2path on files of all type"
15459
15460 test_226b () {
15461         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15462
15463         local MDTIDX=1
15464
15465         rm -rf $DIR/$tdir
15466         mkdir -p $DIR/$tdir
15467         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15468                 error "create remote directory failed"
15469         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15470         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15471                                 "character special file (null)"
15472         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15473                                 "character special file (no device)"
15474         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15475         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15476                                 "block special file (loop)"
15477         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15478         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15479         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15480 }
15481 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15482
15483 # LU-1299 Executing or running ldd on a truncated executable does not
15484 # cause an out-of-memory condition.
15485 test_227() {
15486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15487         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15488
15489         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15490         chmod +x $MOUNT/date
15491
15492         $MOUNT/date > /dev/null
15493         ldd $MOUNT/date > /dev/null
15494         rm -f $MOUNT/date
15495 }
15496 run_test 227 "running truncated executable does not cause OOM"
15497
15498 # LU-1512 try to reuse idle OI blocks
15499 test_228a() {
15500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15501         remote_mds_nodsh && skip "remote MDS with nodsh"
15502         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15503
15504         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15505         local myDIR=$DIR/$tdir
15506
15507         mkdir -p $myDIR
15508         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15509         $LCTL set_param fail_loc=0x80001002
15510         createmany -o $myDIR/t- 10000
15511         $LCTL set_param fail_loc=0
15512         # The guard is current the largest FID holder
15513         touch $myDIR/guard
15514         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15515                     tr -d '[')
15516         local IDX=$(($SEQ % 64))
15517
15518         do_facet $SINGLEMDS sync
15519         # Make sure journal flushed.
15520         sleep 6
15521         local blk1=$(do_facet $SINGLEMDS \
15522                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15523                      grep Blockcount | awk '{print $4}')
15524
15525         # Remove old files, some OI blocks will become idle.
15526         unlinkmany $myDIR/t- 10000
15527         # Create new files, idle OI blocks should be reused.
15528         createmany -o $myDIR/t- 2000
15529         do_facet $SINGLEMDS sync
15530         # Make sure journal flushed.
15531         sleep 6
15532         local blk2=$(do_facet $SINGLEMDS \
15533                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15534                      grep Blockcount | awk '{print $4}')
15535
15536         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15537 }
15538 run_test 228a "try to reuse idle OI blocks"
15539
15540 test_228b() {
15541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15542         remote_mds_nodsh && skip "remote MDS with nodsh"
15543         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15544
15545         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15546         local myDIR=$DIR/$tdir
15547
15548         mkdir -p $myDIR
15549         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15550         $LCTL set_param fail_loc=0x80001002
15551         createmany -o $myDIR/t- 10000
15552         $LCTL set_param fail_loc=0
15553         # The guard is current the largest FID holder
15554         touch $myDIR/guard
15555         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15556                     tr -d '[')
15557         local IDX=$(($SEQ % 64))
15558
15559         do_facet $SINGLEMDS sync
15560         # Make sure journal flushed.
15561         sleep 6
15562         local blk1=$(do_facet $SINGLEMDS \
15563                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15564                      grep Blockcount | awk '{print $4}')
15565
15566         # Remove old files, some OI blocks will become idle.
15567         unlinkmany $myDIR/t- 10000
15568
15569         # stop the MDT
15570         stop $SINGLEMDS || error "Fail to stop MDT."
15571         # remount the MDT
15572         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15573
15574         df $MOUNT || error "Fail to df."
15575         # Create new files, idle OI blocks should be reused.
15576         createmany -o $myDIR/t- 2000
15577         do_facet $SINGLEMDS sync
15578         # Make sure journal flushed.
15579         sleep 6
15580         local blk2=$(do_facet $SINGLEMDS \
15581                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15582                      grep Blockcount | awk '{print $4}')
15583
15584         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15585 }
15586 run_test 228b "idle OI blocks can be reused after MDT restart"
15587
15588 #LU-1881
15589 test_228c() {
15590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15591         remote_mds_nodsh && skip "remote MDS with nodsh"
15592         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15593
15594         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15595         local myDIR=$DIR/$tdir
15596
15597         mkdir -p $myDIR
15598         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15599         $LCTL set_param fail_loc=0x80001002
15600         # 20000 files can guarantee there are index nodes in the OI file
15601         createmany -o $myDIR/t- 20000
15602         $LCTL set_param fail_loc=0
15603         # The guard is current the largest FID holder
15604         touch $myDIR/guard
15605         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15606                     tr -d '[')
15607         local IDX=$(($SEQ % 64))
15608
15609         do_facet $SINGLEMDS sync
15610         # Make sure journal flushed.
15611         sleep 6
15612         local blk1=$(do_facet $SINGLEMDS \
15613                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15614                      grep Blockcount | awk '{print $4}')
15615
15616         # Remove old files, some OI blocks will become idle.
15617         unlinkmany $myDIR/t- 20000
15618         rm -f $myDIR/guard
15619         # The OI file should become empty now
15620
15621         # Create new files, idle OI blocks should be reused.
15622         createmany -o $myDIR/t- 2000
15623         do_facet $SINGLEMDS sync
15624         # Make sure journal flushed.
15625         sleep 6
15626         local blk2=$(do_facet $SINGLEMDS \
15627                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15628                      grep Blockcount | awk '{print $4}')
15629
15630         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15631 }
15632 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15633
15634 test_229() { # LU-2482, LU-3448
15635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15636         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15637         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15638                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15639
15640         rm -f $DIR/$tfile
15641
15642         # Create a file with a released layout and stripe count 2.
15643         $MULTIOP $DIR/$tfile H2c ||
15644                 error "failed to create file with released layout"
15645
15646         $LFS getstripe -v $DIR/$tfile
15647
15648         local pattern=$($LFS getstripe -L $DIR/$tfile)
15649         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15650
15651         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15652                 error "getstripe"
15653         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15654         stat $DIR/$tfile || error "failed to stat released file"
15655
15656         chown $RUNAS_ID $DIR/$tfile ||
15657                 error "chown $RUNAS_ID $DIR/$tfile failed"
15658
15659         chgrp $RUNAS_ID $DIR/$tfile ||
15660                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15661
15662         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15663         rm $DIR/$tfile || error "failed to remove released file"
15664 }
15665 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15666
15667 test_230a() {
15668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15669         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15670         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15671                 skip "Need MDS version at least 2.11.52"
15672
15673         local MDTIDX=1
15674
15675         test_mkdir $DIR/$tdir
15676         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15677         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15678         [ $mdt_idx -ne 0 ] &&
15679                 error "create local directory on wrong MDT $mdt_idx"
15680
15681         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15682                         error "create remote directory failed"
15683         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15684         [ $mdt_idx -ne $MDTIDX ] &&
15685                 error "create remote directory on wrong MDT $mdt_idx"
15686
15687         createmany -o $DIR/$tdir/test_230/t- 10 ||
15688                 error "create files on remote directory failed"
15689         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15690         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15691         rm -r $DIR/$tdir || error "unlink remote directory failed"
15692 }
15693 run_test 230a "Create remote directory and files under the remote directory"
15694
15695 test_230b() {
15696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15697         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15698         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15699                 skip "Need MDS version at least 2.11.52"
15700
15701         local MDTIDX=1
15702         local mdt_index
15703         local i
15704         local file
15705         local pid
15706         local stripe_count
15707         local migrate_dir=$DIR/$tdir/migrate_dir
15708         local other_dir=$DIR/$tdir/other_dir
15709
15710         test_mkdir $DIR/$tdir
15711         test_mkdir -i0 -c1 $migrate_dir
15712         test_mkdir -i0 -c1 $other_dir
15713         for ((i=0; i<10; i++)); do
15714                 mkdir -p $migrate_dir/dir_${i}
15715                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15716                         error "create files under remote dir failed $i"
15717         done
15718
15719         cp /etc/passwd $migrate_dir/$tfile
15720         cp /etc/passwd $other_dir/$tfile
15721         chattr +SAD $migrate_dir
15722         chattr +SAD $migrate_dir/$tfile
15723
15724         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15725         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15726         local old_dir_mode=$(stat -c%f $migrate_dir)
15727         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15728
15729         mkdir -p $migrate_dir/dir_default_stripe2
15730         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15731         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15732
15733         mkdir -p $other_dir
15734         ln $migrate_dir/$tfile $other_dir/luna
15735         ln $migrate_dir/$tfile $migrate_dir/sofia
15736         ln $other_dir/$tfile $migrate_dir/david
15737         ln -s $migrate_dir/$tfile $other_dir/zachary
15738         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15739         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15740
15741         $LFS migrate -m $MDTIDX $migrate_dir ||
15742                 error "fails on migrating remote dir to MDT1"
15743
15744         echo "migratate to MDT1, then checking.."
15745         for ((i = 0; i < 10; i++)); do
15746                 for file in $(find $migrate_dir/dir_${i}); do
15747                         mdt_index=$($LFS getstripe -m $file)
15748                         [ $mdt_index == $MDTIDX ] ||
15749                                 error "$file is not on MDT${MDTIDX}"
15750                 done
15751         done
15752
15753         # the multiple link file should still in MDT0
15754         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15755         [ $mdt_index == 0 ] ||
15756                 error "$file is not on MDT${MDTIDX}"
15757
15758         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15759         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15760                 error " expect $old_dir_flag get $new_dir_flag"
15761
15762         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15763         [ "$old_file_flag" = "$new_file_flag" ] ||
15764                 error " expect $old_file_flag get $new_file_flag"
15765
15766         local new_dir_mode=$(stat -c%f $migrate_dir)
15767         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15768                 error "expect mode $old_dir_mode get $new_dir_mode"
15769
15770         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15771         [ "$old_file_mode" = "$new_file_mode" ] ||
15772                 error "expect mode $old_file_mode get $new_file_mode"
15773
15774         diff /etc/passwd $migrate_dir/$tfile ||
15775                 error "$tfile different after migration"
15776
15777         diff /etc/passwd $other_dir/luna ||
15778                 error "luna different after migration"
15779
15780         diff /etc/passwd $migrate_dir/sofia ||
15781                 error "sofia different after migration"
15782
15783         diff /etc/passwd $migrate_dir/david ||
15784                 error "david different after migration"
15785
15786         diff /etc/passwd $other_dir/zachary ||
15787                 error "zachary different after migration"
15788
15789         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15790                 error "${tfile}_ln different after migration"
15791
15792         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15793                 error "${tfile}_ln_other different after migration"
15794
15795         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15796         [ $stripe_count = 2 ] ||
15797                 error "dir strpe_count $d != 2 after migration."
15798
15799         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15800         [ $stripe_count = 2 ] ||
15801                 error "file strpe_count $d != 2 after migration."
15802
15803         #migrate back to MDT0
15804         MDTIDX=0
15805
15806         $LFS migrate -m $MDTIDX $migrate_dir ||
15807                 error "fails on migrating remote dir to MDT0"
15808
15809         echo "migrate back to MDT0, checking.."
15810         for file in $(find $migrate_dir); do
15811                 mdt_index=$($LFS getstripe -m $file)
15812                 [ $mdt_index == $MDTIDX ] ||
15813                         error "$file is not on MDT${MDTIDX}"
15814         done
15815
15816         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15817         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15818                 error " expect $old_dir_flag get $new_dir_flag"
15819
15820         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15821         [ "$old_file_flag" = "$new_file_flag" ] ||
15822                 error " expect $old_file_flag get $new_file_flag"
15823
15824         local new_dir_mode=$(stat -c%f $migrate_dir)
15825         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15826                 error "expect mode $old_dir_mode get $new_dir_mode"
15827
15828         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15829         [ "$old_file_mode" = "$new_file_mode" ] ||
15830                 error "expect mode $old_file_mode get $new_file_mode"
15831
15832         diff /etc/passwd ${migrate_dir}/$tfile ||
15833                 error "$tfile different after migration"
15834
15835         diff /etc/passwd ${other_dir}/luna ||
15836                 error "luna different after migration"
15837
15838         diff /etc/passwd ${migrate_dir}/sofia ||
15839                 error "sofia different after migration"
15840
15841         diff /etc/passwd ${other_dir}/zachary ||
15842                 error "zachary different after migration"
15843
15844         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15845                 error "${tfile}_ln different after migration"
15846
15847         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15848                 error "${tfile}_ln_other different after migration"
15849
15850         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15851         [ $stripe_count = 2 ] ||
15852                 error "dir strpe_count $d != 2 after migration."
15853
15854         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15855         [ $stripe_count = 2 ] ||
15856                 error "file strpe_count $d != 2 after migration."
15857
15858         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15859 }
15860 run_test 230b "migrate directory"
15861
15862 test_230c() {
15863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15864         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15865         remote_mds_nodsh && skip "remote MDS with nodsh"
15866         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15867                 skip "Need MDS version at least 2.11.52"
15868
15869         local MDTIDX=1
15870         local total=3
15871         local mdt_index
15872         local file
15873         local migrate_dir=$DIR/$tdir/migrate_dir
15874
15875         #If migrating directory fails in the middle, all entries of
15876         #the directory is still accessiable.
15877         test_mkdir $DIR/$tdir
15878         test_mkdir -i0 -c1 $migrate_dir
15879         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15880         stat $migrate_dir
15881         createmany -o $migrate_dir/f $total ||
15882                 error "create files under ${migrate_dir} failed"
15883
15884         # fail after migrating top dir, and this will fail only once, so the
15885         # first sub file migration will fail (currently f3), others succeed.
15886         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15887         do_facet mds1 lctl set_param fail_loc=0x1801
15888         local t=$(ls $migrate_dir | wc -l)
15889         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15890                 error "migrate should fail"
15891         local u=$(ls $migrate_dir | wc -l)
15892         [ "$u" == "$t" ] || error "$u != $t during migration"
15893
15894         # add new dir/file should succeed
15895         mkdir $migrate_dir/dir ||
15896                 error "mkdir failed under migrating directory"
15897         touch $migrate_dir/file ||
15898                 error "create file failed under migrating directory"
15899
15900         # add file with existing name should fail
15901         for file in $migrate_dir/f*; do
15902                 stat $file > /dev/null || error "stat $file failed"
15903                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15904                         error "open(O_CREAT|O_EXCL) $file should fail"
15905                 $MULTIOP $file m && error "create $file should fail"
15906                 touch $DIR/$tdir/remote_dir/$tfile ||
15907                         error "touch $tfile failed"
15908                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15909                         error "link $file should fail"
15910                 mdt_index=$($LFS getstripe -m $file)
15911                 if [ $mdt_index == 0 ]; then
15912                         # file failed to migrate is not allowed to rename to
15913                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15914                                 error "rename to $file should fail"
15915                 else
15916                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15917                                 error "rename to $file failed"
15918                 fi
15919                 echo hello >> $file || error "write $file failed"
15920         done
15921
15922         # resume migration with different options should fail
15923         $LFS migrate -m 0 $migrate_dir &&
15924                 error "migrate -m 0 $migrate_dir should fail"
15925
15926         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15927                 error "migrate -c 2 $migrate_dir should fail"
15928
15929         # resume migration should succeed
15930         $LFS migrate -m $MDTIDX $migrate_dir ||
15931                 error "migrate $migrate_dir failed"
15932
15933         echo "Finish migration, then checking.."
15934         for file in $(find $migrate_dir); do
15935                 mdt_index=$($LFS getstripe -m $file)
15936                 [ $mdt_index == $MDTIDX ] ||
15937                         error "$file is not on MDT${MDTIDX}"
15938         done
15939
15940         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15941 }
15942 run_test 230c "check directory accessiblity if migration failed"
15943
15944 test_230d() {
15945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15946         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15947         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15948                 skip "Need MDS version at least 2.11.52"
15949         # LU-11235
15950         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15951
15952         local migrate_dir=$DIR/$tdir/migrate_dir
15953         local old_index
15954         local new_index
15955         local old_count
15956         local new_count
15957         local new_hash
15958         local mdt_index
15959         local i
15960         local j
15961
15962         old_index=$((RANDOM % MDSCOUNT))
15963         old_count=$((MDSCOUNT - old_index))
15964         new_index=$((RANDOM % MDSCOUNT))
15965         new_count=$((MDSCOUNT - new_index))
15966         new_hash="all_char"
15967
15968         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15969         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15970
15971         test_mkdir $DIR/$tdir
15972         test_mkdir -i $old_index -c $old_count $migrate_dir
15973
15974         for ((i=0; i<100; i++)); do
15975                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15976                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15977                         error "create files under remote dir failed $i"
15978         done
15979
15980         echo -n "Migrate from MDT$old_index "
15981         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15982         echo -n "to MDT$new_index"
15983         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
15984         echo
15985
15986         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
15987         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
15988                 error "migrate remote dir error"
15989
15990         echo "Finish migration, then checking.."
15991         for file in $(find $migrate_dir); do
15992                 mdt_index=$($LFS getstripe -m $file)
15993                 if [ $mdt_index -lt $new_index ] ||
15994                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
15995                         error "$file is on MDT$mdt_index"
15996                 fi
15997         done
15998
15999         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16000 }
16001 run_test 230d "check migrate big directory"
16002
16003 test_230e() {
16004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16005         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16006         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16007                 skip "Need MDS version at least 2.11.52"
16008
16009         local i
16010         local j
16011         local a_fid
16012         local b_fid
16013
16014         mkdir -p $DIR/$tdir
16015         mkdir $DIR/$tdir/migrate_dir
16016         mkdir $DIR/$tdir/other_dir
16017         touch $DIR/$tdir/migrate_dir/a
16018         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16019         ls $DIR/$tdir/other_dir
16020
16021         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16022                 error "migrate dir fails"
16023
16024         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16025         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16026
16027         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16028         [ $mdt_index == 0 ] || error "a is not on MDT0"
16029
16030         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16031                 error "migrate dir fails"
16032
16033         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16034         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16035
16036         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16037         [ $mdt_index == 1 ] || error "a is not on MDT1"
16038
16039         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16040         [ $mdt_index == 1 ] || error "b is not on MDT1"
16041
16042         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16043         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16044
16045         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16046
16047         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16048 }
16049 run_test 230e "migrate mulitple local link files"
16050
16051 test_230f() {
16052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16053         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16054         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16055                 skip "Need MDS version at least 2.11.52"
16056
16057         local a_fid
16058         local ln_fid
16059
16060         mkdir -p $DIR/$tdir
16061         mkdir $DIR/$tdir/migrate_dir
16062         $LFS mkdir -i1 $DIR/$tdir/other_dir
16063         touch $DIR/$tdir/migrate_dir/a
16064         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16065         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16066         ls $DIR/$tdir/other_dir
16067
16068         # a should be migrated to MDT1, since no other links on MDT0
16069         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16070                 error "#1 migrate dir fails"
16071         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16072         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16073         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16074         [ $mdt_index == 1 ] || error "a is not on MDT1"
16075
16076         # a should stay on MDT1, because it is a mulitple link file
16077         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16078                 error "#2 migrate dir fails"
16079         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16080         [ $mdt_index == 1 ] || error "a is not on MDT1"
16081
16082         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16083                 error "#3 migrate dir fails"
16084
16085         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16086         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16087         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16088
16089         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16090         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16091
16092         # a should be migrated to MDT0, since no other links on MDT1
16093         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16094                 error "#4 migrate dir fails"
16095         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16096         [ $mdt_index == 0 ] || error "a is not on MDT0"
16097
16098         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16099 }
16100 run_test 230f "migrate mulitple remote link files"
16101
16102 test_230g() {
16103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16105         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16106                 skip "Need MDS version at least 2.11.52"
16107
16108         mkdir -p $DIR/$tdir/migrate_dir
16109
16110         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16111                 error "migrating dir to non-exist MDT succeeds"
16112         true
16113 }
16114 run_test 230g "migrate dir to non-exist MDT"
16115
16116 test_230h() {
16117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16118         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16119         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16120                 skip "Need MDS version at least 2.11.52"
16121
16122         local mdt_index
16123
16124         mkdir -p $DIR/$tdir/migrate_dir
16125
16126         $LFS migrate -m1 $DIR &&
16127                 error "migrating mountpoint1 should fail"
16128
16129         $LFS migrate -m1 $DIR/$tdir/.. &&
16130                 error "migrating mountpoint2 should fail"
16131
16132         # same as mv
16133         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16134                 error "migrating $tdir/migrate_dir/.. should fail"
16135
16136         true
16137 }
16138 run_test 230h "migrate .. and root"
16139
16140 test_230i() {
16141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16142         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16143         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16144                 skip "Need MDS version at least 2.11.52"
16145
16146         mkdir -p $DIR/$tdir/migrate_dir
16147
16148         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16149                 error "migration fails with a tailing slash"
16150
16151         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16152                 error "migration fails with two tailing slashes"
16153 }
16154 run_test 230i "lfs migrate -m tolerates trailing slashes"
16155
16156 test_230j() {
16157         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16158         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16159                 skip "Need MDS version at least 2.11.52"
16160
16161         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16162         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16163                 error "create $tfile failed"
16164         cat /etc/passwd > $DIR/$tdir/$tfile
16165
16166         $LFS migrate -m 1 $DIR/$tdir
16167
16168         cmp /etc/passwd $DIR/$tdir/$tfile ||
16169                 error "DoM file mismatch after migration"
16170 }
16171 run_test 230j "DoM file data not changed after dir migration"
16172
16173 test_230k() {
16174         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16175         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16176                 skip "Need MDS version at least 2.11.56"
16177
16178         local total=20
16179         local files_on_starting_mdt=0
16180
16181         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16182         $LFS getdirstripe $DIR/$tdir
16183         for i in $(seq $total); do
16184                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16185                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16186                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16187         done
16188
16189         echo "$files_on_starting_mdt files on MDT0"
16190
16191         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16192         $LFS getdirstripe $DIR/$tdir
16193
16194         files_on_starting_mdt=0
16195         for i in $(seq $total); do
16196                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16197                         error "file $tfile.$i mismatch after migration"
16198                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16199                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16200         done
16201
16202         echo "$files_on_starting_mdt files on MDT1 after migration"
16203         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16204
16205         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16206         $LFS getdirstripe $DIR/$tdir
16207
16208         files_on_starting_mdt=0
16209         for i in $(seq $total); do
16210                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16211                         error "file $tfile.$i mismatch after 2nd migration"
16212                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16213                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16214         done
16215
16216         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16217         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16218
16219         true
16220 }
16221 run_test 230k "file data not changed after dir migration"
16222
16223 test_230l() {
16224         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16225         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16226                 skip "Need MDS version at least 2.11.56"
16227
16228         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16229         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16230                 error "create files under remote dir failed $i"
16231         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16232 }
16233 run_test 230l "readdir between MDTs won't crash"
16234
16235 test_231a()
16236 {
16237         # For simplicity this test assumes that max_pages_per_rpc
16238         # is the same across all OSCs
16239         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16240         local bulk_size=$((max_pages * PAGE_SIZE))
16241         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16242                                        head -n 1)
16243
16244         mkdir -p $DIR/$tdir
16245         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16246                 error "failed to set stripe with -S ${brw_size}M option"
16247
16248         # clear the OSC stats
16249         $LCTL set_param osc.*.stats=0 &>/dev/null
16250         stop_writeback
16251
16252         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
16253         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
16254                 oflag=direct &>/dev/null || error "dd failed"
16255
16256         sync; sleep 1; sync # just to be safe
16257         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
16258         if [ x$nrpcs != "x1" ]; then
16259                 $LCTL get_param osc.*.stats
16260                 error "found $nrpcs ost_write RPCs, not 1 as expected"
16261         fi
16262
16263         start_writeback
16264         # Drop the OSC cache, otherwise we will read from it
16265         cancel_lru_locks osc
16266
16267         # clear the OSC stats
16268         $LCTL set_param osc.*.stats=0 &>/dev/null
16269
16270         # Client reads $bulk_size.
16271         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
16272                 iflag=direct &>/dev/null || error "dd failed"
16273
16274         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
16275         if [ x$nrpcs != "x1" ]; then
16276                 $LCTL get_param osc.*.stats
16277                 error "found $nrpcs ost_read RPCs, not 1 as expected"
16278         fi
16279 }
16280 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
16281
16282 test_231b() {
16283         mkdir -p $DIR/$tdir
16284         local i
16285         for i in {0..1023}; do
16286                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
16287                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
16288                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
16289         done
16290         sync
16291 }
16292 run_test 231b "must not assert on fully utilized OST request buffer"
16293
16294 test_232a() {
16295         mkdir -p $DIR/$tdir
16296         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16297
16298         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16299         do_facet ost1 $LCTL set_param fail_loc=0x31c
16300
16301         # ignore dd failure
16302         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
16303
16304         do_facet ost1 $LCTL set_param fail_loc=0
16305         umount_client $MOUNT || error "umount failed"
16306         mount_client $MOUNT || error "mount failed"
16307         stop ost1 || error "cannot stop ost1"
16308         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16309 }
16310 run_test 232a "failed lock should not block umount"
16311
16312 test_232b() {
16313         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
16314                 skip "Need MDS version at least 2.10.58"
16315
16316         mkdir -p $DIR/$tdir
16317         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16318         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
16319         sync
16320         cancel_lru_locks osc
16321
16322         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16323         do_facet ost1 $LCTL set_param fail_loc=0x31c
16324
16325         # ignore failure
16326         $LFS data_version $DIR/$tdir/$tfile || true
16327
16328         do_facet ost1 $LCTL set_param fail_loc=0
16329         umount_client $MOUNT || error "umount failed"
16330         mount_client $MOUNT || error "mount failed"
16331         stop ost1 || error "cannot stop ost1"
16332         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16333 }
16334 run_test 232b "failed data version lock should not block umount"
16335
16336 test_233a() {
16337         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
16338                 skip "Need MDS version at least 2.3.64"
16339         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16340
16341         local fid=$($LFS path2fid $MOUNT)
16342
16343         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16344                 error "cannot access $MOUNT using its FID '$fid'"
16345 }
16346 run_test 233a "checking that OBF of the FS root succeeds"
16347
16348 test_233b() {
16349         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
16350                 skip "Need MDS version at least 2.5.90"
16351         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16352
16353         local fid=$($LFS path2fid $MOUNT/.lustre)
16354
16355         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16356                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
16357
16358         fid=$($LFS path2fid $MOUNT/.lustre/fid)
16359         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16360                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
16361 }
16362 run_test 233b "checking that OBF of the FS .lustre succeeds"
16363
16364 test_234() {
16365         local p="$TMP/sanityN-$TESTNAME.parameters"
16366         save_lustre_params client "llite.*.xattr_cache" > $p
16367         lctl set_param llite.*.xattr_cache 1 ||
16368                 skip_env "xattr cache is not supported"
16369
16370         mkdir -p $DIR/$tdir || error "mkdir failed"
16371         touch $DIR/$tdir/$tfile || error "touch failed"
16372         # OBD_FAIL_LLITE_XATTR_ENOMEM
16373         $LCTL set_param fail_loc=0x1405
16374         getfattr -n user.attr $DIR/$tdir/$tfile &&
16375                 error "getfattr should have failed with ENOMEM"
16376         $LCTL set_param fail_loc=0x0
16377         rm -rf $DIR/$tdir
16378
16379         restore_lustre_params < $p
16380         rm -f $p
16381 }
16382 run_test 234 "xattr cache should not crash on ENOMEM"
16383
16384 test_235() {
16385         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
16386                 skip "Need MDS version at least 2.4.52"
16387
16388         flock_deadlock $DIR/$tfile
16389         local RC=$?
16390         case $RC in
16391                 0)
16392                 ;;
16393                 124) error "process hangs on a deadlock"
16394                 ;;
16395                 *) error "error executing flock_deadlock $DIR/$tfile"
16396                 ;;
16397         esac
16398 }
16399 run_test 235 "LU-1715: flock deadlock detection does not work properly"
16400
16401 #LU-2935
16402 test_236() {
16403         check_swap_layouts_support
16404
16405         local ref1=/etc/passwd
16406         local ref2=/etc/group
16407         local file1=$DIR/$tdir/f1
16408         local file2=$DIR/$tdir/f2
16409
16410         test_mkdir -c1 $DIR/$tdir
16411         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
16412         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
16413         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
16414         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
16415         local fd=$(free_fd)
16416         local cmd="exec $fd<>$file2"
16417         eval $cmd
16418         rm $file2
16419         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
16420                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
16421         cmd="exec $fd>&-"
16422         eval $cmd
16423         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16424
16425         #cleanup
16426         rm -rf $DIR/$tdir
16427 }
16428 run_test 236 "Layout swap on open unlinked file"
16429
16430 # LU-4659 linkea consistency
16431 test_238() {
16432         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16433                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16434                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16435                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16436
16437         touch $DIR/$tfile
16438         ln $DIR/$tfile $DIR/$tfile.lnk
16439         touch $DIR/$tfile.new
16440         mv $DIR/$tfile.new $DIR/$tfile
16441         local fid1=$($LFS path2fid $DIR/$tfile)
16442         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
16443         local path1=$($LFS fid2path $FSNAME "$fid1")
16444         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
16445         local path2=$($LFS fid2path $FSNAME "$fid2")
16446         [ $tfile.lnk == $path2 ] ||
16447                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
16448         rm -f $DIR/$tfile*
16449 }
16450 run_test 238 "Verify linkea consistency"
16451
16452 test_239A() { # was test_239
16453         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16454                 skip "Need MDS version at least 2.5.60"
16455
16456         local list=$(comma_list $(mdts_nodes))
16457
16458         mkdir -p $DIR/$tdir
16459         createmany -o $DIR/$tdir/f- 5000
16460         unlinkmany $DIR/$tdir/f- 5000
16461         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16462                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16463         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16464                         osp.*MDT*.sync_in_flight" | calc_sum)
16465         [ "$changes" -eq 0 ] || error "$changes not synced"
16466 }
16467 run_test 239A "osp_sync test"
16468
16469 test_239a() { #LU-5297
16470         remote_mds_nodsh && skip "remote MDS with nodsh"
16471
16472         touch $DIR/$tfile
16473         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16474         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16475         chgrp $RUNAS_GID $DIR/$tfile
16476         wait_delete_completed
16477 }
16478 run_test 239a "process invalid osp sync record correctly"
16479
16480 test_239b() { #LU-5297
16481         remote_mds_nodsh && skip "remote MDS with nodsh"
16482
16483         touch $DIR/$tfile1
16484         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16485         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16486         chgrp $RUNAS_GID $DIR/$tfile1
16487         wait_delete_completed
16488         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16489         touch $DIR/$tfile2
16490         chgrp $RUNAS_GID $DIR/$tfile2
16491         wait_delete_completed
16492 }
16493 run_test 239b "process osp sync record with ENOMEM error correctly"
16494
16495 test_240() {
16496         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16497         remote_mds_nodsh && skip "remote MDS with nodsh"
16498
16499         mkdir -p $DIR/$tdir
16500
16501         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16502                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16503         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16504                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16505
16506         umount_client $MOUNT || error "umount failed"
16507         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16508         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16509         mount_client $MOUNT || error "failed to mount client"
16510
16511         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16512         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16513 }
16514 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16515
16516 test_241_bio() {
16517         local count=$1
16518         local bsize=$2
16519
16520         for LOOP in $(seq $count); do
16521                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16522                 cancel_lru_locks $OSC || true
16523         done
16524 }
16525
16526 test_241_dio() {
16527         local count=$1
16528         local bsize=$2
16529
16530         for LOOP in $(seq $1); do
16531                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16532                         2>/dev/null
16533         done
16534 }
16535
16536 test_241a() { # was test_241
16537         local bsize=$PAGE_SIZE
16538
16539         (( bsize < 40960 )) && bsize=40960
16540         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16541         ls -la $DIR/$tfile
16542         cancel_lru_locks $OSC
16543         test_241_bio 1000 $bsize &
16544         PID=$!
16545         test_241_dio 1000 $bsize
16546         wait $PID
16547 }
16548 run_test 241a "bio vs dio"
16549
16550 test_241b() {
16551         local bsize=$PAGE_SIZE
16552
16553         (( bsize < 40960 )) && bsize=40960
16554         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16555         ls -la $DIR/$tfile
16556         test_241_dio 1000 $bsize &
16557         PID=$!
16558         test_241_dio 1000 $bsize
16559         wait $PID
16560 }
16561 run_test 241b "dio vs dio"
16562
16563 test_242() {
16564         remote_mds_nodsh && skip "remote MDS with nodsh"
16565
16566         mkdir -p $DIR/$tdir
16567         touch $DIR/$tdir/$tfile
16568
16569         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16570         do_facet mds1 lctl set_param fail_loc=0x105
16571         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16572
16573         do_facet mds1 lctl set_param fail_loc=0
16574         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16575 }
16576 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16577
16578 test_243()
16579 {
16580         test_mkdir $DIR/$tdir
16581         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16582 }
16583 run_test 243 "various group lock tests"
16584
16585 test_244()
16586 {
16587         test_mkdir $DIR/$tdir
16588         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16589         sendfile_grouplock $DIR/$tdir/$tfile || \
16590                 error "sendfile+grouplock failed"
16591         rm -rf $DIR/$tdir
16592 }
16593 run_test 244 "sendfile with group lock tests"
16594
16595 test_245() {
16596         local flagname="multi_mod_rpcs"
16597         local connect_data_name="max_mod_rpcs"
16598         local out
16599
16600         # check if multiple modify RPCs flag is set
16601         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16602                 grep "connect_flags:")
16603         echo "$out"
16604
16605         echo "$out" | grep -qw $flagname
16606         if [ $? -ne 0 ]; then
16607                 echo "connect flag $flagname is not set"
16608                 return
16609         fi
16610
16611         # check if multiple modify RPCs data is set
16612         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16613         echo "$out"
16614
16615         echo "$out" | grep -qw $connect_data_name ||
16616                 error "import should have connect data $connect_data_name"
16617 }
16618 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16619
16620 test_246() { # LU-7371
16621         remote_ost_nodsh && skip "remote OST with nodsh"
16622         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16623                 skip "Need OST version >= 2.7.62"
16624
16625         do_facet ost1 $LCTL set_param fail_val=4095
16626 #define OBD_FAIL_OST_READ_SIZE          0x234
16627         do_facet ost1 $LCTL set_param fail_loc=0x234
16628         $LFS setstripe $DIR/$tfile -i 0 -c 1
16629         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16630         cancel_lru_locks $FSNAME-OST0000
16631         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16632 }
16633 run_test 246 "Read file of size 4095 should return right length"
16634
16635 cleanup_247() {
16636         local submount=$1
16637
16638         trap 0
16639         umount_client $submount
16640         rmdir $submount
16641 }
16642
16643 test_247a() {
16644         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16645                 grep -q subtree ||
16646                 skip_env "Fileset feature is not supported"
16647
16648         local submount=${MOUNT}_$tdir
16649
16650         mkdir $MOUNT/$tdir
16651         mkdir -p $submount || error "mkdir $submount failed"
16652         FILESET="$FILESET/$tdir" mount_client $submount ||
16653                 error "mount $submount failed"
16654         trap "cleanup_247 $submount" EXIT
16655         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16656         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16657                 error "read $MOUNT/$tdir/$tfile failed"
16658         cleanup_247 $submount
16659 }
16660 run_test 247a "mount subdir as fileset"
16661
16662 test_247b() {
16663         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16664                 skip_env "Fileset feature is not supported"
16665
16666         local submount=${MOUNT}_$tdir
16667
16668         rm -rf $MOUNT/$tdir
16669         mkdir -p $submount || error "mkdir $submount failed"
16670         SKIP_FILESET=1
16671         FILESET="$FILESET/$tdir" mount_client $submount &&
16672                 error "mount $submount should fail"
16673         rmdir $submount
16674 }
16675 run_test 247b "mount subdir that dose not exist"
16676
16677 test_247c() {
16678         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16679                 skip_env "Fileset feature is not supported"
16680
16681         local submount=${MOUNT}_$tdir
16682
16683         mkdir -p $MOUNT/$tdir/dir1
16684         mkdir -p $submount || error "mkdir $submount failed"
16685         trap "cleanup_247 $submount" EXIT
16686         FILESET="$FILESET/$tdir" mount_client $submount ||
16687                 error "mount $submount failed"
16688         local fid=$($LFS path2fid $MOUNT/)
16689         $LFS fid2path $submount $fid && error "fid2path should fail"
16690         cleanup_247 $submount
16691 }
16692 run_test 247c "running fid2path outside root"
16693
16694 test_247d() {
16695         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16696                 skip "Fileset feature is not supported"
16697
16698         local submount=${MOUNT}_$tdir
16699
16700         mkdir -p $MOUNT/$tdir/dir1
16701         mkdir -p $submount || error "mkdir $submount failed"
16702         FILESET="$FILESET/$tdir" mount_client $submount ||
16703                 error "mount $submount failed"
16704         trap "cleanup_247 $submount" EXIT
16705         local fid=$($LFS path2fid $submount/dir1)
16706         $LFS fid2path $submount $fid || error "fid2path should succeed"
16707         cleanup_247 $submount
16708 }
16709 run_test 247d "running fid2path inside root"
16710
16711 # LU-8037
16712 test_247e() {
16713         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16714                 grep -q subtree ||
16715                 skip "Fileset feature is not supported"
16716
16717         local submount=${MOUNT}_$tdir
16718
16719         mkdir $MOUNT/$tdir
16720         mkdir -p $submount || error "mkdir $submount failed"
16721         FILESET="$FILESET/.." mount_client $submount &&
16722                 error "mount $submount should fail"
16723         rmdir $submount
16724 }
16725 run_test 247e "mount .. as fileset"
16726
16727 test_248() {
16728         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16729         [ -z "$fast_read_sav" ] && skip "no fast read support"
16730
16731         # create a large file for fast read verification
16732         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16733
16734         # make sure the file is created correctly
16735         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16736                 { rm -f $DIR/$tfile; skip "file creation error"; }
16737
16738         echo "Test 1: verify that fast read is 4 times faster on cache read"
16739
16740         # small read with fast read enabled
16741         $LCTL set_param -n llite.*.fast_read=1
16742         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16743                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16744                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16745         # small read with fast read disabled
16746         $LCTL set_param -n llite.*.fast_read=0
16747         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16748                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16749                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16750
16751         # verify that fast read is 4 times faster for cache read
16752         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16753                 error_not_in_vm "fast read was not 4 times faster: " \
16754                            "$t_fast vs $t_slow"
16755
16756         echo "Test 2: verify the performance between big and small read"
16757         $LCTL set_param -n llite.*.fast_read=1
16758
16759         # 1k non-cache read
16760         cancel_lru_locks osc
16761         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16762                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16763                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16764
16765         # 1M non-cache read
16766         cancel_lru_locks osc
16767         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16768                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16769                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16770
16771         # verify that big IO is not 4 times faster than small IO
16772         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16773                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16774
16775         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16776         rm -f $DIR/$tfile
16777 }
16778 run_test 248 "fast read verification"
16779
16780 test_249() { # LU-7890
16781         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16782                 skip "Need at least version 2.8.54"
16783
16784         rm -f $DIR/$tfile
16785         $LFS setstripe -c 1 $DIR/$tfile
16786         # Offset 2T == 4k * 512M
16787         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16788                 error "dd to 2T offset failed"
16789 }
16790 run_test 249 "Write above 2T file size"
16791
16792 test_250() {
16793         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16794          && skip "no 16TB file size limit on ZFS"
16795
16796         $LFS setstripe -c 1 $DIR/$tfile
16797         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16798         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16799         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16800         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16801                 conv=notrunc,fsync && error "append succeeded"
16802         return 0
16803 }
16804 run_test 250 "Write above 16T limit"
16805
16806 test_251() {
16807         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16808
16809         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16810         #Skip once - writing the first stripe will succeed
16811         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16812         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16813                 error "short write happened"
16814
16815         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16816         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16817                 error "short read happened"
16818
16819         rm -f $DIR/$tfile
16820 }
16821 run_test 251 "Handling short read and write correctly"
16822
16823 test_252() {
16824         remote_mds_nodsh && skip "remote MDS with nodsh"
16825         remote_ost_nodsh && skip "remote OST with nodsh"
16826         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
16827                 skip_env "ldiskfs only test"
16828         fi
16829
16830         local tgt
16831         local dev
16832         local out
16833         local uuid
16834         local num
16835         local gen
16836
16837         # check lr_reader on OST0000
16838         tgt=ost1
16839         dev=$(facet_device $tgt)
16840         out=$(do_facet $tgt $LR_READER $dev)
16841         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16842         echo "$out"
16843         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16844         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16845                 error "Invalid uuid returned by $LR_READER on target $tgt"
16846         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16847
16848         # check lr_reader -c on MDT0000
16849         tgt=mds1
16850         dev=$(facet_device $tgt)
16851         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16852                 skip "$LR_READER does not support additional options"
16853         fi
16854         out=$(do_facet $tgt $LR_READER -c $dev)
16855         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16856         echo "$out"
16857         num=$(echo "$out" | grep -c "mdtlov")
16858         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16859                 error "Invalid number of mdtlov clients returned by $LR_READER"
16860         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16861
16862         # check lr_reader -cr on MDT0000
16863         out=$(do_facet $tgt $LR_READER -cr $dev)
16864         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16865         echo "$out"
16866         echo "$out" | grep -q "^reply_data:$" ||
16867                 error "$LR_READER should have returned 'reply_data' section"
16868         num=$(echo "$out" | grep -c "client_generation")
16869         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16870 }
16871 run_test 252 "check lr_reader tool"
16872
16873 test_253() {
16874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16875         remote_mds_nodsh && skip "remote MDS with nodsh"
16876         remote_mgs_nodsh && skip "remote MGS with nodsh"
16877
16878         local ostidx=0
16879         local rc=0
16880         local ost_name=$(ostname_from_index $ostidx)
16881
16882         # on the mdt's osc
16883         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16884         do_facet $SINGLEMDS $LCTL get_param -n \
16885                 osp.$mdtosc_proc1.reserved_mb_high ||
16886                 skip  "remote MDS does not support reserved_mb_high"
16887
16888         rm -rf $DIR/$tdir
16889         wait_mds_ost_sync
16890         wait_delete_completed
16891         mkdir $DIR/$tdir
16892
16893         if ! combined_mgs_mds ; then
16894                 mount_mgs_client
16895         fi
16896         pool_add $TESTNAME || error "Pool creation failed"
16897         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
16898
16899         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16900                 error "Setstripe failed"
16901
16902         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
16903
16904         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
16905                     grep "watermarks")
16906         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
16907
16908         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16909                         osp.$mdtosc_proc1.prealloc_status)
16910         echo "prealloc_status $oa_status"
16911
16912         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
16913                 error "File creation should fail"
16914
16915         #object allocation was stopped, but we still able to append files
16916         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
16917                 oflag=append || error "Append failed"
16918
16919         rm -f $DIR/$tdir/$tfile.0
16920
16921         # For this test, we want to delete the files we created to go out of
16922         # space but leave the watermark, so we remain nearly out of space
16923         ost_watermarks_enospc_delete_files $tfile $ostidx
16924
16925         wait_delete_completed
16926
16927         sleep_maxage
16928
16929         for i in $(seq 10 12); do
16930                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
16931                         2>/dev/null || error "File creation failed after rm"
16932         done
16933
16934         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16935                         osp.$mdtosc_proc1.prealloc_status)
16936         echo "prealloc_status $oa_status"
16937
16938         if (( oa_status != 0 )); then
16939                 error "Object allocation still disable after rm"
16940         fi
16941
16942         if ! combined_mgs_mds ; then
16943                 umount_mgs_client
16944         fi
16945 }
16946 run_test 253 "Check object allocation limit"
16947
16948 test_254() {
16949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16950         remote_mds_nodsh && skip "remote MDS with nodsh"
16951         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
16952                 skip "MDS does not support changelog_size"
16953
16954         local cl_user
16955         local MDT0=$(facet_svc $SINGLEMDS)
16956
16957         changelog_register || error "changelog_register failed"
16958
16959         changelog_clear 0 || error "changelog_clear failed"
16960
16961         local size1=$(do_facet $SINGLEMDS \
16962                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16963         echo "Changelog size $size1"
16964
16965         rm -rf $DIR/$tdir
16966         $LFS mkdir -i 0 $DIR/$tdir
16967         # change something
16968         mkdir -p $DIR/$tdir/pics/2008/zachy
16969         touch $DIR/$tdir/pics/2008/zachy/timestamp
16970         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
16971         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16972         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16973         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16974         rm $DIR/$tdir/pics/desktop.jpg
16975
16976         local size2=$(do_facet $SINGLEMDS \
16977                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16978         echo "Changelog size after work $size2"
16979
16980         (( $size2 > $size1 )) ||
16981                 error "new Changelog size=$size2 less than old size=$size1"
16982 }
16983 run_test 254 "Check changelog size"
16984
16985 ladvise_no_type()
16986 {
16987         local type=$1
16988         local file=$2
16989
16990         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
16991                 awk -F: '{print $2}' | grep $type > /dev/null
16992         if [ $? -ne 0 ]; then
16993                 return 0
16994         fi
16995         return 1
16996 }
16997
16998 ladvise_no_ioctl()
16999 {
17000         local file=$1
17001
17002         lfs ladvise -a willread $file > /dev/null 2>&1
17003         if [ $? -eq 0 ]; then
17004                 return 1
17005         fi
17006
17007         lfs ladvise -a willread $file 2>&1 |
17008                 grep "Inappropriate ioctl for device" > /dev/null
17009         if [ $? -eq 0 ]; then
17010                 return 0
17011         fi
17012         return 1
17013 }
17014
17015 percent() {
17016         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17017 }
17018
17019 # run a random read IO workload
17020 # usage: random_read_iops <filename> <filesize> <iosize>
17021 random_read_iops() {
17022         local file=$1
17023         local fsize=$2
17024         local iosize=${3:-4096}
17025
17026         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17027                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17028 }
17029
17030 drop_file_oss_cache() {
17031         local file="$1"
17032         local nodes="$2"
17033
17034         $LFS ladvise -a dontneed $file 2>/dev/null ||
17035                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17036 }
17037
17038 ladvise_willread_performance()
17039 {
17040         local repeat=10
17041         local average_origin=0
17042         local average_cache=0
17043         local average_ladvise=0
17044
17045         for ((i = 1; i <= $repeat; i++)); do
17046                 echo "Iter $i/$repeat: reading without willread hint"
17047                 cancel_lru_locks osc
17048                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17049                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17050                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17051                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17052
17053                 cancel_lru_locks osc
17054                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17055                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17056                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17057
17058                 cancel_lru_locks osc
17059                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17060                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17061                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17062                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17063                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17064         done
17065         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17066         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17067         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17068
17069         speedup_cache=$(percent $average_cache $average_origin)
17070         speedup_ladvise=$(percent $average_ladvise $average_origin)
17071
17072         echo "Average uncached read: $average_origin"
17073         echo "Average speedup with OSS cached read: " \
17074                 "$average_cache = +$speedup_cache%"
17075         echo "Average speedup with ladvise willread: " \
17076                 "$average_ladvise = +$speedup_ladvise%"
17077
17078         local lowest_speedup=20
17079         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17080                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17081                         "got $average_cache%. Skipping ladvise willread check."
17082                 return 0
17083         fi
17084
17085         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17086         # it is still good to run until then to exercise 'ladvise willread'
17087         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17088                 [ "$ost1_FSTYPE" = "zfs" ] &&
17089                 echo "osd-zfs does not support dontneed or drop_caches" &&
17090                 return 0
17091
17092         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17093         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17094                 error_not_in_vm "Speedup with willread is less than " \
17095                         "$lowest_speedup%, got $average_ladvise%"
17096 }
17097
17098 test_255a() {
17099         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17100                 skip "lustre < 2.8.54 does not support ladvise "
17101         remote_ost_nodsh && skip "remote OST with nodsh"
17102
17103         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17104
17105         ladvise_no_type willread $DIR/$tfile &&
17106                 skip "willread ladvise is not supported"
17107
17108         ladvise_no_ioctl $DIR/$tfile &&
17109                 skip "ladvise ioctl is not supported"
17110
17111         local size_mb=100
17112         local size=$((size_mb * 1048576))
17113         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17114                 error "dd to $DIR/$tfile failed"
17115
17116         lfs ladvise -a willread $DIR/$tfile ||
17117                 error "Ladvise failed with no range argument"
17118
17119         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17120                 error "Ladvise failed with no -l or -e argument"
17121
17122         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17123                 error "Ladvise failed with only -e argument"
17124
17125         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17126                 error "Ladvise failed with only -l argument"
17127
17128         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17129                 error "End offset should not be smaller than start offset"
17130
17131         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17132                 error "End offset should not be equal to start offset"
17133
17134         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17135                 error "Ladvise failed with overflowing -s argument"
17136
17137         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17138                 error "Ladvise failed with overflowing -e argument"
17139
17140         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17141                 error "Ladvise failed with overflowing -l argument"
17142
17143         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17144                 error "Ladvise succeeded with conflicting -l and -e arguments"
17145
17146         echo "Synchronous ladvise should wait"
17147         local delay=4
17148 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17149         do_nodes $(comma_list $(osts_nodes)) \
17150                 $LCTL set_param fail_val=$delay fail_loc=0x237
17151
17152         local start_ts=$SECONDS
17153         lfs ladvise -a willread $DIR/$tfile ||
17154                 error "Ladvise failed with no range argument"
17155         local end_ts=$SECONDS
17156         local inteval_ts=$((end_ts - start_ts))
17157
17158         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17159                 error "Synchronous advice didn't wait reply"
17160         fi
17161
17162         echo "Asynchronous ladvise shouldn't wait"
17163         local start_ts=$SECONDS
17164         lfs ladvise -a willread -b $DIR/$tfile ||
17165                 error "Ladvise failed with no range argument"
17166         local end_ts=$SECONDS
17167         local inteval_ts=$((end_ts - start_ts))
17168
17169         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17170                 error "Asynchronous advice blocked"
17171         fi
17172
17173         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
17174         ladvise_willread_performance
17175 }
17176 run_test 255a "check 'lfs ladvise -a willread'"
17177
17178 facet_meminfo() {
17179         local facet=$1
17180         local info=$2
17181
17182         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
17183 }
17184
17185 test_255b() {
17186         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17187                 skip "lustre < 2.8.54 does not support ladvise "
17188         remote_ost_nodsh && skip "remote OST with nodsh"
17189
17190         lfs setstripe -c 1 -i 0 $DIR/$tfile
17191
17192         ladvise_no_type dontneed $DIR/$tfile &&
17193                 skip "dontneed ladvise is not supported"
17194
17195         ladvise_no_ioctl $DIR/$tfile &&
17196                 skip "ladvise ioctl is not supported"
17197
17198         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17199                 [ "$ost1_FSTYPE" = "zfs" ] &&
17200                 skip "zfs-osd does not support 'ladvise dontneed'"
17201
17202         local size_mb=100
17203         local size=$((size_mb * 1048576))
17204         # In order to prevent disturbance of other processes, only check 3/4
17205         # of the memory usage
17206         local kibibytes=$((size_mb * 1024 * 3 / 4))
17207
17208         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17209                 error "dd to $DIR/$tfile failed"
17210
17211         #force write to complete before dropping OST cache & checking memory
17212         sync
17213
17214         local total=$(facet_meminfo ost1 MemTotal)
17215         echo "Total memory: $total KiB"
17216
17217         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
17218         local before_read=$(facet_meminfo ost1 Cached)
17219         echo "Cache used before read: $before_read KiB"
17220
17221         lfs ladvise -a willread $DIR/$tfile ||
17222                 error "Ladvise willread failed"
17223         local after_read=$(facet_meminfo ost1 Cached)
17224         echo "Cache used after read: $after_read KiB"
17225
17226         lfs ladvise -a dontneed $DIR/$tfile ||
17227                 error "Ladvise dontneed again failed"
17228         local no_read=$(facet_meminfo ost1 Cached)
17229         echo "Cache used after dontneed ladvise: $no_read KiB"
17230
17231         if [ $total -lt $((before_read + kibibytes)) ]; then
17232                 echo "Memory is too small, abort checking"
17233                 return 0
17234         fi
17235
17236         if [ $((before_read + kibibytes)) -gt $after_read ]; then
17237                 error "Ladvise willread should use more memory" \
17238                         "than $kibibytes KiB"
17239         fi
17240
17241         if [ $((no_read + kibibytes)) -gt $after_read ]; then
17242                 error "Ladvise dontneed should release more memory" \
17243                         "than $kibibytes KiB"
17244         fi
17245 }
17246 run_test 255b "check 'lfs ladvise -a dontneed'"
17247
17248 test_255c() {
17249         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
17250                 skip "lustre < 2.10.53 does not support lockahead"
17251
17252         local count
17253         local new_count
17254         local difference
17255         local i
17256         local rc
17257
17258         test_mkdir -p $DIR/$tdir
17259         $LFS setstripe -i 0 -c 1 $DIR/$tdir
17260
17261         #test 10 returns only success/failure
17262         i=10
17263         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17264         rc=$?
17265         if [ $rc -eq 255 ]; then
17266                 error "Ladvise test${i} failed, ${rc}"
17267         fi
17268
17269         #test 11 counts lock enqueue requests, all others count new locks
17270         i=11
17271         count=$(do_facet ost1 \
17272                 $LCTL get_param -n ost.OSS.ost.stats)
17273         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
17274
17275         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17276         rc=$?
17277         if [ $rc -eq 255 ]; then
17278                 error "Ladvise test${i} failed, ${rc}"
17279         fi
17280
17281         new_count=$(do_facet ost1 \
17282                 $LCTL get_param -n ost.OSS.ost.stats)
17283         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
17284                    awk '{ print $2 }')
17285
17286         difference="$((new_count - count))"
17287         if [ $difference -ne $rc ]; then
17288                 error "Ladvise test${i}, bad enqueue count, returned " \
17289                       "${rc}, actual ${difference}"
17290         fi
17291
17292         for i in $(seq 12 21); do
17293                 # If we do not do this, we run the risk of having too many
17294                 # locks and starting lock cancellation while we are checking
17295                 # lock counts.
17296                 cancel_lru_locks osc
17297
17298                 count=$($LCTL get_param -n \
17299                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17300
17301                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
17302                 rc=$?
17303                 if [ $rc -eq 255 ]; then
17304                         error "Ladvise test ${i} failed, ${rc}"
17305                 fi
17306
17307                 new_count=$($LCTL get_param -n \
17308                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17309                 difference="$((new_count - count))"
17310
17311                 # Test 15 output is divided by 100 to map down to valid return
17312                 if [ $i -eq 15 ]; then
17313                         rc="$((rc * 100))"
17314                 fi
17315
17316                 if [ $difference -ne $rc ]; then
17317                         error "Ladvise test ${i}, bad lock count, returned " \
17318                               "${rc}, actual ${difference}"
17319                 fi
17320         done
17321
17322         #test 22 returns only success/failure
17323         i=22
17324         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17325         rc=$?
17326         if [ $rc -eq 255 ]; then
17327                 error "Ladvise test${i} failed, ${rc}"
17328         fi
17329 }
17330 run_test 255c "suite of ladvise lockahead tests"
17331
17332 test_256() {
17333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17334         remote_mds_nodsh && skip "remote MDS with nodsh"
17335         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17336         changelog_users $SINGLEMDS | grep "^cl" &&
17337                 skip "active changelog user"
17338
17339         local cl_user
17340         local cat_sl
17341         local mdt_dev
17342
17343         mdt_dev=$(mdsdevname 1)
17344         echo $mdt_dev
17345
17346         changelog_register || error "changelog_register failed"
17347
17348         rm -rf $DIR/$tdir
17349         mkdir -p $DIR/$tdir
17350
17351         changelog_clear 0 || error "changelog_clear failed"
17352
17353         # change something
17354         touch $DIR/$tdir/{1..10}
17355
17356         # stop the MDT
17357         stop $SINGLEMDS || error "Fail to stop MDT"
17358
17359         # remount the MDT
17360
17361         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
17362
17363         #after mount new plainllog is used
17364         touch $DIR/$tdir/{11..19}
17365         local tmpfile=$(mktemp -u $tfile.XXXXXX)
17366         cat_sl=$(do_facet $SINGLEMDS "sync; \
17367                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17368                  llog_reader $tmpfile | grep -c type=1064553b")
17369         do_facet $SINGLEMDS llog_reader $tmpfile
17370
17371         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
17372
17373         changelog_clear 0 || error "changelog_clear failed"
17374
17375         cat_sl=$(do_facet $SINGLEMDS "sync; \
17376                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17377                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
17378
17379         if (( cat_sl == 2 )); then
17380                 error "Empty plain llog was not deleted from changelog catalog"
17381         elif (( cat_sl != 1 )); then
17382                 error "Active plain llog shouldn't be deleted from catalog"
17383         fi
17384 }
17385 run_test 256 "Check llog delete for empty and not full state"
17386
17387 test_257() {
17388         remote_mds_nodsh && skip "remote MDS with nodsh"
17389         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
17390                 skip "Need MDS version at least 2.8.55"
17391
17392         test_mkdir $DIR/$tdir
17393
17394         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
17395                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
17396         stat $DIR/$tdir
17397
17398 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17399         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17400         local facet=mds$((mdtidx + 1))
17401         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17402         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17403
17404         stop $facet || error "stop MDS failed"
17405         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17406                 error "start MDS fail"
17407         wait_recovery_complete $facet
17408 }
17409 run_test 257 "xattr locks are not lost"
17410
17411 # Verify we take the i_mutex when security requires it
17412 test_258a() {
17413 #define OBD_FAIL_IMUTEX_SEC 0x141c
17414         $LCTL set_param fail_loc=0x141c
17415         touch $DIR/$tfile
17416         chmod u+s $DIR/$tfile
17417         chmod a+rwx $DIR/$tfile
17418         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17419         RC=$?
17420         if [ $RC -ne 0 ]; then
17421                 error "error, failed to take i_mutex, rc=$?"
17422         fi
17423         rm -f $DIR/$tfile
17424 }
17425 run_test 258a "verify i_mutex security behavior when suid attributes is set"
17426
17427 # Verify we do NOT take the i_mutex in the normal case
17428 test_258b() {
17429 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17430         $LCTL set_param fail_loc=0x141d
17431         touch $DIR/$tfile
17432         chmod a+rwx $DIR
17433         chmod a+rw $DIR/$tfile
17434         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17435         RC=$?
17436         if [ $RC -ne 0 ]; then
17437                 error "error, took i_mutex unnecessarily, rc=$?"
17438         fi
17439         rm -f $DIR/$tfile
17440
17441 }
17442 run_test 258b "verify i_mutex security behavior"
17443
17444 test_259() {
17445         local file=$DIR/$tfile
17446         local before
17447         local after
17448
17449         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17450
17451         stack_trap "rm -f $file" EXIT
17452
17453         wait_delete_completed
17454         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17455         echo "before: $before"
17456
17457         $LFS setstripe -i 0 -c 1 $file
17458         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17459         sync_all_data
17460         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17461         echo "after write: $after"
17462
17463 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17464         do_facet ost1 $LCTL set_param fail_loc=0x2301
17465         $TRUNCATE $file 0
17466         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17467         echo "after truncate: $after"
17468
17469         stop ost1
17470         do_facet ost1 $LCTL set_param fail_loc=0
17471         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17472         sleep 2
17473         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17474         echo "after restart: $after"
17475         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17476                 error "missing truncate?"
17477
17478         return 0
17479 }
17480 run_test 259 "crash at delayed truncate"
17481
17482 test_260() {
17483 #define OBD_FAIL_MDC_CLOSE               0x806
17484         $LCTL set_param fail_loc=0x80000806
17485         touch $DIR/$tfile
17486
17487 }
17488 run_test 260 "Check mdc_close fail"
17489
17490 ### Data-on-MDT sanity tests ###
17491 test_270a() {
17492         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17493                 skip "Need MDS version at least 2.10.55 for DoM"
17494
17495         # create DoM file
17496         local dom=$DIR/$tdir/dom_file
17497         local tmp=$DIR/$tdir/tmp_file
17498
17499         mkdir -p $DIR/$tdir
17500
17501         # basic checks for DoM component creation
17502         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17503                 error "Can set MDT layout to non-first entry"
17504
17505         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17506                 error "Can define multiple entries as MDT layout"
17507
17508         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17509
17510         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17511         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17512         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17513
17514         local mdtidx=$($LFS getstripe -m $dom)
17515         local mdtname=MDT$(printf %04x $mdtidx)
17516         local facet=mds$((mdtidx + 1))
17517         local space_check=1
17518
17519         # Skip free space checks with ZFS
17520         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17521
17522         # write
17523         sync
17524         local size_tmp=$((65536 * 3))
17525         local mdtfree1=$(do_facet $facet \
17526                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17527
17528         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17529         # check also direct IO along write
17530         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17531         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17532         sync
17533         cmp $tmp $dom || error "file data is different"
17534         [ $(stat -c%s $dom) == $size_tmp ] ||
17535                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17536         if [ $space_check == 1 ]; then
17537                 local mdtfree2=$(do_facet $facet \
17538                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17539
17540                 # increase in usage from by $size_tmp
17541                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17542                         error "MDT free space wrong after write: " \
17543                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17544         fi
17545
17546         # truncate
17547         local size_dom=10000
17548
17549         $TRUNCATE $dom $size_dom
17550         [ $(stat -c%s $dom) == $size_dom ] ||
17551                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17552         if [ $space_check == 1 ]; then
17553                 mdtfree1=$(do_facet $facet \
17554                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17555                 # decrease in usage from $size_tmp to new $size_dom
17556                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17557                   $(((size_tmp - size_dom) / 1024)) ] ||
17558                         error "MDT free space is wrong after truncate: " \
17559                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17560         fi
17561
17562         # append
17563         cat $tmp >> $dom
17564         sync
17565         size_dom=$((size_dom + size_tmp))
17566         [ $(stat -c%s $dom) == $size_dom ] ||
17567                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17568         if [ $space_check == 1 ]; then
17569                 mdtfree2=$(do_facet $facet \
17570                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17571                 # increase in usage by $size_tmp from previous
17572                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17573                         error "MDT free space is wrong after append: " \
17574                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17575         fi
17576
17577         # delete
17578         rm $dom
17579         if [ $space_check == 1 ]; then
17580                 mdtfree1=$(do_facet $facet \
17581                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17582                 # decrease in usage by $size_dom from previous
17583                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17584                         error "MDT free space is wrong after removal: " \
17585                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17586         fi
17587
17588         # combined striping
17589         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17590                 error "Can't create DoM + OST striping"
17591
17592         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17593         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17594         # check also direct IO along write
17595         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17596         sync
17597         cmp $tmp $dom || error "file data is different"
17598         [ $(stat -c%s $dom) == $size_tmp ] ||
17599                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17600         rm $dom $tmp
17601
17602         return 0
17603 }
17604 run_test 270a "DoM: basic functionality tests"
17605
17606 test_270b() {
17607         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17608                 skip "Need MDS version at least 2.10.55"
17609
17610         local dom=$DIR/$tdir/dom_file
17611         local max_size=1048576
17612
17613         mkdir -p $DIR/$tdir
17614         $LFS setstripe -E $max_size -L mdt $dom
17615
17616         # truncate over the limit
17617         $TRUNCATE $dom $(($max_size + 1)) &&
17618                 error "successful truncate over the maximum size"
17619         # write over the limit
17620         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17621                 error "successful write over the maximum size"
17622         # append over the limit
17623         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17624         echo "12345" >> $dom && error "successful append over the maximum size"
17625         rm $dom
17626
17627         return 0
17628 }
17629 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17630
17631 test_270c() {
17632         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17633                 skip "Need MDS version at least 2.10.55"
17634
17635         mkdir -p $DIR/$tdir
17636         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17637
17638         # check files inherit DoM EA
17639         touch $DIR/$tdir/first
17640         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17641                 error "bad pattern"
17642         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17643                 error "bad stripe count"
17644         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17645                 error "bad stripe size"
17646
17647         # check directory inherits DoM EA and uses it as default
17648         mkdir $DIR/$tdir/subdir
17649         touch $DIR/$tdir/subdir/second
17650         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17651                 error "bad pattern in sub-directory"
17652         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17653                 error "bad stripe count in sub-directory"
17654         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17655                 error "bad stripe size in sub-directory"
17656         return 0
17657 }
17658 run_test 270c "DoM: DoM EA inheritance tests"
17659
17660 test_270d() {
17661         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17662                 skip "Need MDS version at least 2.10.55"
17663
17664         mkdir -p $DIR/$tdir
17665         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17666
17667         # inherit default DoM striping
17668         mkdir $DIR/$tdir/subdir
17669         touch $DIR/$tdir/subdir/f1
17670
17671         # change default directory striping
17672         $LFS setstripe -c 1 $DIR/$tdir/subdir
17673         touch $DIR/$tdir/subdir/f2
17674         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17675                 error "wrong default striping in file 2"
17676         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17677                 error "bad pattern in file 2"
17678         return 0
17679 }
17680 run_test 270d "DoM: change striping from DoM to RAID0"
17681
17682 test_270e() {
17683         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17684                 skip "Need MDS version at least 2.10.55"
17685
17686         mkdir -p $DIR/$tdir/dom
17687         mkdir -p $DIR/$tdir/norm
17688         DOMFILES=20
17689         NORMFILES=10
17690         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17691         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17692
17693         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17694         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17695
17696         # find DoM files by layout
17697         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17698         [ $NUM -eq  $DOMFILES ] ||
17699                 error "lfs find -L: found $NUM, expected $DOMFILES"
17700         echo "Test 1: lfs find 20 DOM files by layout: OK"
17701
17702         # there should be 1 dir with default DOM striping
17703         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17704         [ $NUM -eq  1 ] ||
17705                 error "lfs find -L: found $NUM, expected 1 dir"
17706         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17707
17708         # find DoM files by stripe size
17709         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17710         [ $NUM -eq  $DOMFILES ] ||
17711                 error "lfs find -S: found $NUM, expected $DOMFILES"
17712         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17713
17714         # find files by stripe offset except DoM files
17715         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17716         [ $NUM -eq  $NORMFILES ] ||
17717                 error "lfs find -i: found $NUM, expected $NORMFILES"
17718         echo "Test 5: lfs find no DOM files by stripe index: OK"
17719         return 0
17720 }
17721 run_test 270e "DoM: lfs find with DoM files test"
17722
17723 test_270f() {
17724         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17725                 skip "Need MDS version at least 2.10.55"
17726
17727         local mdtname=${FSNAME}-MDT0000-mdtlov
17728         local dom=$DIR/$tdir/dom_file
17729         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17730                                                 lod.$mdtname.dom_stripesize)
17731         local dom_limit=131072
17732
17733         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17734         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17735                                                 lod.$mdtname.dom_stripesize)
17736         [ ${dom_limit} -eq ${dom_current} ] ||
17737                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17738
17739         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17740         $LFS setstripe -d $DIR/$tdir
17741         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17742                 error "Can't set directory default striping"
17743
17744         # exceed maximum stripe size
17745         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17746                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17747         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17748                 error "Able to create DoM component size more than LOD limit"
17749
17750         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17751         dom_current=$(do_facet mds1 $LCTL get_param -n \
17752                                                 lod.$mdtname.dom_stripesize)
17753         [ 0 -eq ${dom_current} ] ||
17754                 error "Can't set zero DoM stripe limit"
17755         rm $dom
17756
17757         # attempt to create DoM file on server with disabled DoM should
17758         # remove DoM entry from layout and be succeed
17759         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17760                 error "Can't create DoM file (DoM is disabled)"
17761         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17762                 error "File has DoM component while DoM is disabled"
17763         rm $dom
17764
17765         # attempt to create DoM file with only DoM stripe should return error
17766         $LFS setstripe -E $dom_limit -L mdt $dom &&
17767                 error "Able to create DoM-only file while DoM is disabled"
17768
17769         # too low values to be aligned with smallest stripe size 64K
17770         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17771         dom_current=$(do_facet mds1 $LCTL get_param -n \
17772                                                 lod.$mdtname.dom_stripesize)
17773         [ 30000 -eq ${dom_current} ] &&
17774                 error "Can set too small DoM stripe limit"
17775
17776         # 64K is a minimal stripe size in Lustre, expect limit of that size
17777         [ 65536 -eq ${dom_current} ] ||
17778                 error "Limit is not set to 64K but ${dom_current}"
17779
17780         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17781         dom_current=$(do_facet mds1 $LCTL get_param -n \
17782                                                 lod.$mdtname.dom_stripesize)
17783         echo $dom_current
17784         [ 2147483648 -eq ${dom_current} ] &&
17785                 error "Can set too large DoM stripe limit"
17786
17787         do_facet mds1 $LCTL set_param -n \
17788                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17789         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17790                 error "Can't create DoM component size after limit change"
17791         do_facet mds1 $LCTL set_param -n \
17792                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17793         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17794                 error "Can't create DoM file after limit decrease"
17795         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17796                 error "Can create big DoM component after limit decrease"
17797         touch ${dom}_def ||
17798                 error "Can't create file with old default layout"
17799
17800         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17801         return 0
17802 }
17803 run_test 270f "DoM: maximum DoM stripe size checks"
17804
17805 test_271a() {
17806         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17807                 skip "Need MDS version at least 2.10.55"
17808
17809         local dom=$DIR/$tdir/dom
17810
17811         mkdir -p $DIR/$tdir
17812
17813         $LFS setstripe -E 1024K -L mdt $dom
17814
17815         lctl set_param -n mdc.*.stats=clear
17816         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17817         cat $dom > /dev/null
17818         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17819         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17820         ls $dom
17821         rm -f $dom
17822 }
17823 run_test 271a "DoM: data is cached for read after write"
17824
17825 test_271b() {
17826         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17827                 skip "Need MDS version at least 2.10.55"
17828
17829         local dom=$DIR/$tdir/dom
17830
17831         mkdir -p $DIR/$tdir
17832
17833         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17834
17835         lctl set_param -n mdc.*.stats=clear
17836         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17837         cancel_lru_locks mdc
17838         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17839         # second stat to check size is cached on client
17840         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17841         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17842         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17843         rm -f $dom
17844 }
17845 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17846
17847 test_271ba() {
17848         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17849                 skip "Need MDS version at least 2.10.55"
17850
17851         local dom=$DIR/$tdir/dom
17852
17853         mkdir -p $DIR/$tdir
17854
17855         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17856
17857         lctl set_param -n mdc.*.stats=clear
17858         lctl set_param -n osc.*.stats=clear
17859         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17860         cancel_lru_locks mdc
17861         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17862         # second stat to check size is cached on client
17863         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17864         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17865         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17866         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17867         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17868         rm -f $dom
17869 }
17870 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17871
17872
17873 get_mdc_stats() {
17874         local mdtidx=$1
17875         local param=$2
17876         local mdt=MDT$(printf %04x $mdtidx)
17877
17878         if [ -z $param ]; then
17879                 lctl get_param -n mdc.*$mdt*.stats
17880         else
17881                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17882         fi
17883 }
17884
17885 test_271c() {
17886         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17887                 skip "Need MDS version at least 2.10.55"
17888
17889         local dom=$DIR/$tdir/dom
17890
17891         mkdir -p $DIR/$tdir
17892
17893         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17894
17895         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17896         local facet=mds$((mdtidx + 1))
17897
17898         cancel_lru_locks mdc
17899         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17900         createmany -o $dom 1000
17901         lctl set_param -n mdc.*.stats=clear
17902         smalliomany -w $dom 1000 200
17903         get_mdc_stats $mdtidx
17904         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17905         # Each file has 1 open, 1 IO enqueues, total 2000
17906         # but now we have also +1 getxattr for security.capability, total 3000
17907         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17908         unlinkmany $dom 1000
17909
17910         cancel_lru_locks mdc
17911         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17912         createmany -o $dom 1000
17913         lctl set_param -n mdc.*.stats=clear
17914         smalliomany -w $dom 1000 200
17915         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17916         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17917         # for OPEN and IO lock.
17918         [ $((enq - enq_2)) -ge 1000 ] ||
17919                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17920         unlinkmany $dom 1000
17921         return 0
17922 }
17923 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17924
17925 cleanup_271def_tests() {
17926         trap 0
17927         rm -f $1
17928 }
17929
17930 test_271d() {
17931         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17932                 skip "Need MDS version at least 2.10.57"
17933
17934         local dom=$DIR/$tdir/dom
17935         local tmp=$TMP/$tfile
17936         trap "cleanup_271def_tests $tmp" EXIT
17937
17938         mkdir -p $DIR/$tdir
17939
17940         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17941
17942         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17943
17944         cancel_lru_locks mdc
17945         dd if=/dev/urandom of=$tmp bs=1000 count=1
17946         dd if=$tmp of=$dom bs=1000 count=1
17947         cancel_lru_locks mdc
17948
17949         cat /etc/hosts >> $tmp
17950         lctl set_param -n mdc.*.stats=clear
17951
17952         # append data to the same file it should update local page
17953         echo "Append to the same page"
17954         cat /etc/hosts >> $dom
17955         local num=$(get_mdc_stats $mdtidx ost_read)
17956         local ra=$(get_mdc_stats $mdtidx req_active)
17957         local rw=$(get_mdc_stats $mdtidx req_waittime)
17958
17959         [ -z $num ] || error "$num READ RPC occured"
17960         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17961         echo "... DONE"
17962
17963         # compare content
17964         cmp $tmp $dom || error "file miscompare"
17965
17966         cancel_lru_locks mdc
17967         lctl set_param -n mdc.*.stats=clear
17968
17969         echo "Open and read file"
17970         cat $dom > /dev/null
17971         local num=$(get_mdc_stats $mdtidx ost_read)
17972         local ra=$(get_mdc_stats $mdtidx req_active)
17973         local rw=$(get_mdc_stats $mdtidx req_waittime)
17974
17975         [ -z $num ] || error "$num READ RPC occured"
17976         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17977         echo "... DONE"
17978
17979         # compare content
17980         cmp $tmp $dom || error "file miscompare"
17981
17982         return 0
17983 }
17984 run_test 271d "DoM: read on open (1K file in reply buffer)"
17985
17986 test_271f() {
17987         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17988                 skip "Need MDS version at least 2.10.57"
17989
17990         local dom=$DIR/$tdir/dom
17991         local tmp=$TMP/$tfile
17992         trap "cleanup_271def_tests $tmp" EXIT
17993
17994         mkdir -p $DIR/$tdir
17995
17996         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17997
17998         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17999
18000         cancel_lru_locks mdc
18001         dd if=/dev/urandom of=$tmp bs=200000 count=1
18002         dd if=$tmp of=$dom bs=200000 count=1
18003         cancel_lru_locks mdc
18004         cat /etc/hosts >> $tmp
18005         lctl set_param -n mdc.*.stats=clear
18006
18007         echo "Append to the same page"
18008         cat /etc/hosts >> $dom
18009         local num=$(get_mdc_stats $mdtidx ost_read)
18010         local ra=$(get_mdc_stats $mdtidx req_active)
18011         local rw=$(get_mdc_stats $mdtidx req_waittime)
18012
18013         [ -z $num ] || error "$num READ RPC occured"
18014         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18015         echo "... DONE"
18016
18017         # compare content
18018         cmp $tmp $dom || error "file miscompare"
18019
18020         cancel_lru_locks mdc
18021         lctl set_param -n mdc.*.stats=clear
18022
18023         echo "Open and read file"
18024         cat $dom > /dev/null
18025         local num=$(get_mdc_stats $mdtidx ost_read)
18026         local ra=$(get_mdc_stats $mdtidx req_active)
18027         local rw=$(get_mdc_stats $mdtidx req_waittime)
18028
18029         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18030         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18031         echo "... DONE"
18032
18033         # compare content
18034         cmp $tmp $dom || error "file miscompare"
18035
18036         return 0
18037 }
18038 run_test 271f "DoM: read on open (200K file and read tail)"
18039
18040 test_271g() {
18041         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18042                 skip "Skipping due to old client or server version"
18043
18044         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18045         # to get layout
18046         $CHECKSTAT -t file $DIR1/$tfile
18047
18048         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18049         MULTIOP_PID=$!
18050         sleep 1
18051         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18052         $LCTL set_param fail_loc=0x80000314
18053         rm $DIR1/$tfile || error "Unlink fails"
18054         RC=$?
18055         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18056         [ $RC -eq 0 ] || error "Failed write to stale object"
18057 }
18058 run_test 271g "Discard DoM data vs client flush race"
18059
18060 test_272a() {
18061         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18062                 skip "Need MDS version at least 2.11.50"
18063
18064         local dom=$DIR/$tdir/dom
18065         mkdir -p $DIR/$tdir
18066
18067         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18068         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18069                 error "failed to write data into $dom"
18070         local old_md5=$(md5sum $dom)
18071
18072         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18073                 error "failed to migrate to the same DoM component"
18074
18075         local new_md5=$(md5sum $dom)
18076
18077         [ "$old_md5" == "$new_md5" ] ||
18078                 error "md5sum differ: $old_md5, $new_md5"
18079
18080         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18081                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18082 }
18083 run_test 272a "DoM migration: new layout with the same DOM component"
18084
18085 test_272b() {
18086         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18087                 skip "Need MDS version at least 2.11.50"
18088
18089         local dom=$DIR/$tdir/dom
18090         mkdir -p $DIR/$tdir
18091         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18092
18093         local mdtidx=$($LFS getstripe -m $dom)
18094         local mdtname=MDT$(printf %04x $mdtidx)
18095         local facet=mds$((mdtidx + 1))
18096
18097         local mdtfree1=$(do_facet $facet \
18098                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18099         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18100                 error "failed to write data into $dom"
18101         local old_md5=$(md5sum $dom)
18102         cancel_lru_locks mdc
18103         local mdtfree1=$(do_facet $facet \
18104                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18105
18106         $LFS migrate -c2 $dom ||
18107                 error "failed to migrate to the new composite layout"
18108         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18109                 error "MDT stripe was not removed"
18110
18111         cancel_lru_locks mdc
18112         local new_md5=$(md5sum $dom)
18113         [ "$old_md5" != "$new_md5" ] &&
18114                 error "$old_md5 != $new_md5"
18115
18116         # Skip free space checks with ZFS
18117         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18118                 local mdtfree2=$(do_facet $facet \
18119                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18120                 [ $mdtfree2 -gt $mdtfree1 ] ||
18121                         error "MDT space is not freed after migration"
18122         fi
18123         return 0
18124 }
18125 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18126
18127 test_272c() {
18128         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18129                 skip "Need MDS version at least 2.11.50"
18130
18131         local dom=$DIR/$tdir/$tfile
18132         mkdir -p $DIR/$tdir
18133         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18134
18135         local mdtidx=$($LFS getstripe -m $dom)
18136         local mdtname=MDT$(printf %04x $mdtidx)
18137         local facet=mds$((mdtidx + 1))
18138
18139         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18140                 error "failed to write data into $dom"
18141         local old_md5=$(md5sum $dom)
18142         cancel_lru_locks mdc
18143         local mdtfree1=$(do_facet $facet \
18144                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18145
18146         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18147                 error "failed to migrate to the new composite layout"
18148         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18149                 error "MDT stripe was not removed"
18150
18151         cancel_lru_locks mdc
18152         local new_md5=$(md5sum $dom)
18153         [ "$old_md5" != "$new_md5" ] &&
18154                 error "$old_md5 != $new_md5"
18155
18156         # Skip free space checks with ZFS
18157         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18158                 local mdtfree2=$(do_facet $facet \
18159                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18160                 [ $mdtfree2 -gt $mdtfree1 ] ||
18161                         error "MDS space is not freed after migration"
18162         fi
18163         return 0
18164 }
18165 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18166
18167 test_273a() {
18168         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18169                 skip "Need MDS version at least 2.11.50"
18170
18171         # Layout swap cannot be done if either file has DOM component,
18172         # this will never be supported, migration should be used instead
18173
18174         local dom=$DIR/$tdir/$tfile
18175         mkdir -p $DIR/$tdir
18176
18177         $LFS setstripe -c2 ${dom}_plain
18178         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
18179         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
18180                 error "can swap layout with DoM component"
18181         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
18182                 error "can swap layout with DoM component"
18183
18184         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
18185         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
18186                 error "can swap layout with DoM component"
18187         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
18188                 error "can swap layout with DoM component"
18189         return 0
18190 }
18191 run_test 273a "DoM: layout swapping should fail with DOM"
18192
18193 test_275() {
18194         remote_ost_nodsh && skip "remote OST with nodsh"
18195         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
18196                 skip "Need OST version >= 2.10.57"
18197
18198         local file=$DIR/$tfile
18199         local oss
18200
18201         oss=$(comma_list $(osts_nodes))
18202
18203         dd if=/dev/urandom of=$file bs=1M count=2 ||
18204                 error "failed to create a file"
18205         cancel_lru_locks osc
18206
18207         #lock 1
18208         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18209                 error "failed to read a file"
18210
18211 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
18212         $LCTL set_param fail_loc=0x8000031f
18213
18214         cancel_lru_locks osc &
18215         sleep 1
18216
18217 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
18218         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
18219         #IO takes another lock, but matches the PENDING one
18220         #and places it to the IO RPC
18221         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18222                 error "failed to read a file with PENDING lock"
18223 }
18224 run_test 275 "Read on a canceled duplicate lock"
18225
18226 test_276() {
18227         remote_ost_nodsh && skip "remote OST with nodsh"
18228         local pid
18229
18230         do_facet ost1 "(while true; do \
18231                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
18232                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
18233         pid=$!
18234
18235         for LOOP in $(seq 20); do
18236                 stop ost1
18237                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
18238         done
18239         kill -9 $pid
18240         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
18241                 rm $TMP/sanity_276_pid"
18242 }
18243 run_test 276 "Race between mount and obd_statfs"
18244
18245 cleanup_test_300() {
18246         trap 0
18247         umask $SAVE_UMASK
18248 }
18249 test_striped_dir() {
18250         local mdt_index=$1
18251         local stripe_count
18252         local stripe_index
18253
18254         mkdir -p $DIR/$tdir
18255
18256         SAVE_UMASK=$(umask)
18257         trap cleanup_test_300 RETURN EXIT
18258
18259         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
18260                                                 $DIR/$tdir/striped_dir ||
18261                 error "set striped dir error"
18262
18263         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
18264         [ "$mode" = "755" ] || error "expect 755 got $mode"
18265
18266         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
18267                 error "getdirstripe failed"
18268         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
18269         if [ "$stripe_count" != "2" ]; then
18270                 error "1:stripe_count is $stripe_count, expect 2"
18271         fi
18272         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
18273         if [ "$stripe_count" != "2" ]; then
18274                 error "2:stripe_count is $stripe_count, expect 2"
18275         fi
18276
18277         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
18278         if [ "$stripe_index" != "$mdt_index" ]; then
18279                 error "stripe_index is $stripe_index, expect $mdt_index"
18280         fi
18281
18282         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18283                 error "nlink error after create striped dir"
18284
18285         mkdir $DIR/$tdir/striped_dir/a
18286         mkdir $DIR/$tdir/striped_dir/b
18287
18288         stat $DIR/$tdir/striped_dir/a ||
18289                 error "create dir under striped dir failed"
18290         stat $DIR/$tdir/striped_dir/b ||
18291                 error "create dir under striped dir failed"
18292
18293         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
18294                 error "nlink error after mkdir"
18295
18296         rmdir $DIR/$tdir/striped_dir/a
18297         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
18298                 error "nlink error after rmdir"
18299
18300         rmdir $DIR/$tdir/striped_dir/b
18301         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18302                 error "nlink error after rmdir"
18303
18304         chattr +i $DIR/$tdir/striped_dir
18305         createmany -o $DIR/$tdir/striped_dir/f 10 &&
18306                 error "immutable flags not working under striped dir!"
18307         chattr -i $DIR/$tdir/striped_dir
18308
18309         rmdir $DIR/$tdir/striped_dir ||
18310                 error "rmdir striped dir error"
18311
18312         cleanup_test_300
18313
18314         true
18315 }
18316
18317 test_300a() {
18318         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18319                 skip "skipped for lustre < 2.7.0"
18320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18321         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18322
18323         test_striped_dir 0 || error "failed on striped dir on MDT0"
18324         test_striped_dir 1 || error "failed on striped dir on MDT0"
18325 }
18326 run_test 300a "basic striped dir sanity test"
18327
18328 test_300b() {
18329         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18330                 skip "skipped for lustre < 2.7.0"
18331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18332         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18333
18334         local i
18335         local mtime1
18336         local mtime2
18337         local mtime3
18338
18339         test_mkdir $DIR/$tdir || error "mkdir fail"
18340         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18341                 error "set striped dir error"
18342         for i in {0..9}; do
18343                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
18344                 sleep 1
18345                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
18346                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
18347                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
18348                 sleep 1
18349                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
18350                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
18351                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
18352         done
18353         true
18354 }
18355 run_test 300b "check ctime/mtime for striped dir"
18356
18357 test_300c() {
18358         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18359                 skip "skipped for lustre < 2.7.0"
18360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18361         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18362
18363         local file_count
18364
18365         mkdir -p $DIR/$tdir
18366         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
18367                 error "set striped dir error"
18368
18369         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
18370                 error "chown striped dir failed"
18371
18372         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
18373                 error "create 5k files failed"
18374
18375         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
18376
18377         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
18378
18379         rm -rf $DIR/$tdir
18380 }
18381 run_test 300c "chown && check ls under striped directory"
18382
18383 test_300d() {
18384         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18385                 skip "skipped for lustre < 2.7.0"
18386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18387         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18388
18389         local stripe_count
18390         local file
18391
18392         mkdir -p $DIR/$tdir
18393         $LFS setstripe -c 2 $DIR/$tdir
18394
18395         #local striped directory
18396         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18397                 error "set striped dir error"
18398         createmany -o $DIR/$tdir/striped_dir/f 10 ||
18399                 error "create 10 files failed"
18400
18401         #remote striped directory
18402         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
18403                 error "set striped dir error"
18404         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
18405                 error "create 10 files failed"
18406
18407         for file in $(find $DIR/$tdir); do
18408                 stripe_count=$($LFS getstripe -c $file)
18409                 [ $stripe_count -eq 2 ] ||
18410                         error "wrong stripe $stripe_count for $file"
18411         done
18412
18413         rm -rf $DIR/$tdir
18414 }
18415 run_test 300d "check default stripe under striped directory"
18416
18417 test_300e() {
18418         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18419                 skip "Need MDS version at least 2.7.55"
18420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18421         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18422
18423         local stripe_count
18424         local file
18425
18426         mkdir -p $DIR/$tdir
18427
18428         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18429                 error "set striped dir error"
18430
18431         touch $DIR/$tdir/striped_dir/a
18432         touch $DIR/$tdir/striped_dir/b
18433         touch $DIR/$tdir/striped_dir/c
18434
18435         mkdir $DIR/$tdir/striped_dir/dir_a
18436         mkdir $DIR/$tdir/striped_dir/dir_b
18437         mkdir $DIR/$tdir/striped_dir/dir_c
18438
18439         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18440                 error "set striped adir under striped dir error"
18441
18442         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18443                 error "set striped bdir under striped dir error"
18444
18445         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18446                 error "set striped cdir under striped dir error"
18447
18448         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18449                 error "rename dir under striped dir fails"
18450
18451         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18452                 error "rename dir under different stripes fails"
18453
18454         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18455                 error "rename file under striped dir should succeed"
18456
18457         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18458                 error "rename dir under striped dir should succeed"
18459
18460         rm -rf $DIR/$tdir
18461 }
18462 run_test 300e "check rename under striped directory"
18463
18464 test_300f() {
18465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18466         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18467         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18468                 skip "Need MDS version at least 2.7.55"
18469
18470         local stripe_count
18471         local file
18472
18473         rm -rf $DIR/$tdir
18474         mkdir -p $DIR/$tdir
18475
18476         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18477                 error "set striped dir error"
18478
18479         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18480                 error "set striped dir error"
18481
18482         touch $DIR/$tdir/striped_dir/a
18483         mkdir $DIR/$tdir/striped_dir/dir_a
18484         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18485                 error "create striped dir under striped dir fails"
18486
18487         touch $DIR/$tdir/striped_dir1/b
18488         mkdir $DIR/$tdir/striped_dir1/dir_b
18489         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18490                 error "create striped dir under striped dir fails"
18491
18492         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18493                 error "rename dir under different striped dir should fail"
18494
18495         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18496                 error "rename striped dir under diff striped dir should fail"
18497
18498         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18499                 error "rename file under diff striped dirs fails"
18500
18501         rm -rf $DIR/$tdir
18502 }
18503 run_test 300f "check rename cross striped directory"
18504
18505 test_300_check_default_striped_dir()
18506 {
18507         local dirname=$1
18508         local default_count=$2
18509         local default_index=$3
18510         local stripe_count
18511         local stripe_index
18512         local dir_stripe_index
18513         local dir
18514
18515         echo "checking $dirname $default_count $default_index"
18516         $LFS setdirstripe -D -c $default_count -i $default_index \
18517                                 -t all_char $DIR/$tdir/$dirname ||
18518                 error "set default stripe on striped dir error"
18519         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18520         [ $stripe_count -eq $default_count ] ||
18521                 error "expect $default_count get $stripe_count for $dirname"
18522
18523         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18524         [ $stripe_index -eq $default_index ] ||
18525                 error "expect $default_index get $stripe_index for $dirname"
18526
18527         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18528                                                 error "create dirs failed"
18529
18530         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18531         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18532         for dir in $(find $DIR/$tdir/$dirname/*); do
18533                 stripe_count=$($LFS getdirstripe -c $dir)
18534                 [ $stripe_count -eq $default_count ] ||
18535                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18536                 error "stripe count $default_count != $stripe_count for $dir"
18537
18538                 stripe_index=$($LFS getdirstripe -i $dir)
18539                 [ $default_index -eq -1 ] ||
18540                         [ $stripe_index -eq $default_index ] ||
18541                         error "$stripe_index != $default_index for $dir"
18542
18543                 #check default stripe
18544                 stripe_count=$($LFS getdirstripe -D -c $dir)
18545                 [ $stripe_count -eq $default_count ] ||
18546                 error "default count $default_count != $stripe_count for $dir"
18547
18548                 stripe_index=$($LFS getdirstripe -D -i $dir)
18549                 [ $stripe_index -eq $default_index ] ||
18550                 error "default index $default_index != $stripe_index for $dir"
18551         done
18552         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18553 }
18554
18555 test_300g() {
18556         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18557         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18558                 skip "Need MDS version at least 2.7.55"
18559
18560         local dir
18561         local stripe_count
18562         local stripe_index
18563
18564         mkdir $DIR/$tdir
18565         mkdir $DIR/$tdir/normal_dir
18566
18567         #Checking when client cache stripe index
18568         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18569         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18570                 error "create striped_dir failed"
18571
18572         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18573                 error "create dir0 fails"
18574         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18575         [ $stripe_index -eq 0 ] ||
18576                 error "dir0 expect index 0 got $stripe_index"
18577
18578         mkdir $DIR/$tdir/striped_dir/dir1 ||
18579                 error "create dir1 fails"
18580         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18581         [ $stripe_index -eq 1 ] ||
18582                 error "dir1 expect index 1 got $stripe_index"
18583
18584         #check default stripe count/stripe index
18585         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18586         test_300_check_default_striped_dir normal_dir 1 0
18587         test_300_check_default_striped_dir normal_dir 2 1
18588         test_300_check_default_striped_dir normal_dir 2 -1
18589
18590         #delete default stripe information
18591         echo "delete default stripeEA"
18592         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18593                 error "set default stripe on striped dir error"
18594
18595         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18596         for dir in $(find $DIR/$tdir/normal_dir/*); do
18597                 stripe_count=$($LFS getdirstripe -c $dir)
18598                 [ $stripe_count -eq 0 ] ||
18599                         error "expect 1 get $stripe_count for $dir"
18600                 stripe_index=$($LFS getdirstripe -i $dir)
18601                 [ $stripe_index -eq 0 ] ||
18602                         error "expect 0 get $stripe_index for $dir"
18603         done
18604 }
18605 run_test 300g "check default striped directory for normal directory"
18606
18607 test_300h() {
18608         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18609         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18610                 skip "Need MDS version at least 2.7.55"
18611
18612         local dir
18613         local stripe_count
18614
18615         mkdir $DIR/$tdir
18616         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18617                 error "set striped dir error"
18618
18619         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18620         test_300_check_default_striped_dir striped_dir 1 0
18621         test_300_check_default_striped_dir striped_dir 2 1
18622         test_300_check_default_striped_dir striped_dir 2 -1
18623
18624         #delete default stripe information
18625         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18626                 error "set default stripe on striped dir error"
18627
18628         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18629         for dir in $(find $DIR/$tdir/striped_dir/*); do
18630                 stripe_count=$($LFS getdirstripe -c $dir)
18631                 [ $stripe_count -eq 0 ] ||
18632                         error "expect 1 get $stripe_count for $dir"
18633         done
18634 }
18635 run_test 300h "check default striped directory for striped directory"
18636
18637 test_300i() {
18638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18639         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18640         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18641                 skip "Need MDS version at least 2.7.55"
18642
18643         local stripe_count
18644         local file
18645
18646         mkdir $DIR/$tdir
18647
18648         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18649                 error "set striped dir error"
18650
18651         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18652                 error "create files under striped dir failed"
18653
18654         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18655                 error "set striped hashdir error"
18656
18657         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18658                 error "create dir0 under hash dir failed"
18659         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18660                 error "create dir1 under hash dir failed"
18661
18662         # unfortunately, we need to umount to clear dir layout cache for now
18663         # once we fully implement dir layout, we can drop this
18664         umount_client $MOUNT || error "umount failed"
18665         mount_client $MOUNT || error "mount failed"
18666
18667         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18668         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18669         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18670
18671         #set the stripe to be unknown hash type
18672         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18673         $LCTL set_param fail_loc=0x1901
18674         for ((i = 0; i < 10; i++)); do
18675                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18676                         error "stat f-$i failed"
18677                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18678         done
18679
18680         touch $DIR/$tdir/striped_dir/f0 &&
18681                 error "create under striped dir with unknown hash should fail"
18682
18683         $LCTL set_param fail_loc=0
18684
18685         umount_client $MOUNT || error "umount failed"
18686         mount_client $MOUNT || error "mount failed"
18687
18688         return 0
18689 }
18690 run_test 300i "client handle unknown hash type striped directory"
18691
18692 test_300j() {
18693         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18695         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18696                 skip "Need MDS version at least 2.7.55"
18697
18698         local stripe_count
18699         local file
18700
18701         mkdir $DIR/$tdir
18702
18703         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18704         $LCTL set_param fail_loc=0x1702
18705         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18706                 error "set striped dir error"
18707
18708         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18709                 error "create files under striped dir failed"
18710
18711         $LCTL set_param fail_loc=0
18712
18713         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18714
18715         return 0
18716 }
18717 run_test 300j "test large update record"
18718
18719 test_300k() {
18720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18721         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18722         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18723                 skip "Need MDS version at least 2.7.55"
18724
18725         # this test needs a huge transaction
18726         local kb
18727         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18728         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18729
18730         local stripe_count
18731         local file
18732
18733         mkdir $DIR/$tdir
18734
18735         #define OBD_FAIL_LARGE_STRIPE   0x1703
18736         $LCTL set_param fail_loc=0x1703
18737         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18738                 error "set striped dir error"
18739         $LCTL set_param fail_loc=0
18740
18741         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18742                 error "getstripeddir fails"
18743         rm -rf $DIR/$tdir/striped_dir ||
18744                 error "unlink striped dir fails"
18745
18746         return 0
18747 }
18748 run_test 300k "test large striped directory"
18749
18750 test_300l() {
18751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18752         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18753         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18754                 skip "Need MDS version at least 2.7.55"
18755
18756         local stripe_index
18757
18758         test_mkdir -p $DIR/$tdir/striped_dir
18759         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18760                         error "chown $RUNAS_ID failed"
18761         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18762                 error "set default striped dir failed"
18763
18764         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18765         $LCTL set_param fail_loc=0x80000158
18766         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18767
18768         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18769         [ $stripe_index -eq 1 ] ||
18770                 error "expect 1 get $stripe_index for $dir"
18771 }
18772 run_test 300l "non-root user to create dir under striped dir with stale layout"
18773
18774 test_300m() {
18775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18776         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18777         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18778                 skip "Need MDS version at least 2.7.55"
18779
18780         mkdir -p $DIR/$tdir/striped_dir
18781         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18782                 error "set default stripes dir error"
18783
18784         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18785
18786         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18787         [ $stripe_count -eq 0 ] ||
18788                         error "expect 0 get $stripe_count for a"
18789
18790         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18791                 error "set default stripes dir error"
18792
18793         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18794
18795         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18796         [ $stripe_count -eq 0 ] ||
18797                         error "expect 0 get $stripe_count for b"
18798
18799         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18800                 error "set default stripes dir error"
18801
18802         mkdir $DIR/$tdir/striped_dir/c &&
18803                 error "default stripe_index is invalid, mkdir c should fails"
18804
18805         rm -rf $DIR/$tdir || error "rmdir fails"
18806 }
18807 run_test 300m "setstriped directory on single MDT FS"
18808
18809 cleanup_300n() {
18810         local list=$(comma_list $(mdts_nodes))
18811
18812         trap 0
18813         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18814 }
18815
18816 test_300n() {
18817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18818         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18819         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18820                 skip "Need MDS version at least 2.7.55"
18821         remote_mds_nodsh && skip "remote MDS with nodsh"
18822
18823         local stripe_index
18824         local list=$(comma_list $(mdts_nodes))
18825
18826         trap cleanup_300n RETURN EXIT
18827         mkdir -p $DIR/$tdir
18828         chmod 777 $DIR/$tdir
18829         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18830                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18831                 error "create striped dir succeeds with gid=0"
18832
18833         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18834         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18835                 error "create striped dir fails with gid=-1"
18836
18837         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18838         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18839                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18840                 error "set default striped dir succeeds with gid=0"
18841
18842
18843         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18844         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18845                 error "set default striped dir fails with gid=-1"
18846
18847
18848         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18849         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18850                                         error "create test_dir fails"
18851         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18852                                         error "create test_dir1 fails"
18853         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18854                                         error "create test_dir2 fails"
18855         cleanup_300n
18856 }
18857 run_test 300n "non-root user to create dir under striped dir with default EA"
18858
18859 test_300o() {
18860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18861         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18862         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18863                 skip "Need MDS version at least 2.7.55"
18864
18865         local numfree1
18866         local numfree2
18867
18868         mkdir -p $DIR/$tdir
18869
18870         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18871         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18872         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
18873                 skip "not enough free inodes $numfree1 $numfree2"
18874         fi
18875
18876         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18877         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18878         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
18879                 skip "not enough free space $numfree1 $numfree2"
18880         fi
18881
18882         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18883                 error "setdirstripe fails"
18884
18885         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18886                 error "create dirs fails"
18887
18888         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18889         ls $DIR/$tdir/striped_dir > /dev/null ||
18890                 error "ls striped dir fails"
18891         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18892                 error "unlink big striped dir fails"
18893 }
18894 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18895
18896 test_300p() {
18897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18898         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18899         remote_mds_nodsh && skip "remote MDS with nodsh"
18900
18901         mkdir -p $DIR/$tdir
18902
18903         #define OBD_FAIL_OUT_ENOSPC     0x1704
18904         do_facet mds2 lctl set_param fail_loc=0x80001704
18905         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18906                  && error "create striped directory should fail"
18907
18908         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18909
18910         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18911         true
18912 }
18913 run_test 300p "create striped directory without space"
18914
18915 test_300q() {
18916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18917         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18918
18919         local fd=$(free_fd)
18920         local cmd="exec $fd<$tdir"
18921         cd $DIR
18922         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18923         eval $cmd
18924         cmd="exec $fd<&-"
18925         trap "eval $cmd" EXIT
18926         cd $tdir || error "cd $tdir fails"
18927         rmdir  ../$tdir || error "rmdir $tdir fails"
18928         mkdir local_dir && error "create dir succeeds"
18929         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
18930         eval $cmd
18931         return 0
18932 }
18933 run_test 300q "create remote directory under orphan directory"
18934
18935 test_300r() {
18936         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
18937                 skip "Need MDS version at least 2.7.55" && return
18938         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18939
18940         mkdir $DIR/$tdir
18941
18942         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
18943                 error "set striped dir error"
18944
18945         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18946                 error "getstripeddir fails"
18947
18948         local stripe_count
18949         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18950                       awk '/lmv_stripe_count:/ { print $2 }')
18951
18952         [ $MDSCOUNT -ne $stripe_count ] &&
18953                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
18954
18955         rm -rf $DIR/$tdir/striped_dir ||
18956                 error "unlink striped dir fails"
18957 }
18958 run_test 300r "test -1 striped directory"
18959
18960 prepare_remote_file() {
18961         mkdir $DIR/$tdir/src_dir ||
18962                 error "create remote source failed"
18963
18964         cp /etc/hosts $DIR/$tdir/src_dir/a ||
18965                  error "cp to remote source failed"
18966         touch $DIR/$tdir/src_dir/a
18967
18968         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
18969                 error "create remote target dir failed"
18970
18971         touch $DIR/$tdir/tgt_dir/b
18972
18973         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
18974                 error "rename dir cross MDT failed!"
18975
18976         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
18977                 error "src_child still exists after rename"
18978
18979         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
18980                 error "missing file(a) after rename"
18981
18982         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
18983                 error "diff after rename"
18984 }
18985
18986 test_310a() {
18987         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18989
18990         local remote_file=$DIR/$tdir/tgt_dir/b
18991
18992         mkdir -p $DIR/$tdir
18993
18994         prepare_remote_file || error "prepare remote file failed"
18995
18996         #open-unlink file
18997         $OPENUNLINK $remote_file $remote_file ||
18998                 error "openunlink $remote_file failed"
18999         $CHECKSTAT -a $remote_file || error "$remote_file exists"
19000 }
19001 run_test 310a "open unlink remote file"
19002
19003 test_310b() {
19004         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19006
19007         local remote_file=$DIR/$tdir/tgt_dir/b
19008
19009         mkdir -p $DIR/$tdir
19010
19011         prepare_remote_file || error "prepare remote file failed"
19012
19013         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19014         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19015         $CHECKSTAT -t file $remote_file || error "check file failed"
19016 }
19017 run_test 310b "unlink remote file with multiple links while open"
19018
19019 test_310c() {
19020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19021         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19022
19023         local remote_file=$DIR/$tdir/tgt_dir/b
19024
19025         mkdir -p $DIR/$tdir
19026
19027         prepare_remote_file || error "prepare remote file failed"
19028
19029         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19030         multiop_bg_pause $remote_file O_uc ||
19031                         error "mulitop failed for remote file"
19032         MULTIPID=$!
19033         $MULTIOP $DIR/$tfile Ouc
19034         kill -USR1 $MULTIPID
19035         wait $MULTIPID
19036 }
19037 run_test 310c "open-unlink remote file with multiple links"
19038
19039 #LU-4825
19040 test_311() {
19041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19042         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19043         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
19044                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
19045         remote_mds_nodsh && skip "remote MDS with nodsh"
19046
19047         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19048         local mdts=$(comma_list $(mdts_nodes))
19049
19050         mkdir -p $DIR/$tdir
19051         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19052         createmany -o $DIR/$tdir/$tfile. 1000
19053
19054         # statfs data is not real time, let's just calculate it
19055         old_iused=$((old_iused + 1000))
19056
19057         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19058                         osp.*OST0000*MDT0000.create_count")
19059         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19060                                 osp.*OST0000*MDT0000.max_create_count")
19061         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
19062
19063         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
19064         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
19065         [ $index -ne 0 ] || error "$tfile stripe index is 0"
19066
19067         unlinkmany $DIR/$tdir/$tfile. 1000
19068
19069         do_nodes $mdts "$LCTL set_param -n \
19070                         osp.*OST0000*.max_create_count=$max_count"
19071         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
19072                 do_nodes $mdts "$LCTL set_param -n \
19073                                 osp.*OST0000*.create_count=$count"
19074         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
19075                         grep "=0" && error "create_count is zero"
19076
19077         local new_iused
19078         for i in $(seq 120); do
19079                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19080                 # system may be too busy to destroy all objs in time, use
19081                 # a somewhat small value to not fail autotest
19082                 [ $((old_iused - new_iused)) -gt 400 ] && break
19083                 sleep 1
19084         done
19085
19086         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
19087         [ $((old_iused - new_iused)) -gt 400 ] ||
19088                 error "objs not destroyed after unlink"
19089 }
19090 run_test 311 "disable OSP precreate, and unlink should destroy objs"
19091
19092 zfs_oid_to_objid()
19093 {
19094         local ost=$1
19095         local objid=$2
19096
19097         local vdevdir=$(dirname $(facet_vdevice $ost))
19098         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
19099         local zfs_zapid=$(do_facet $ost $cmd |
19100                           grep -w "/O/0/d$((objid%32))" -C 5 |
19101                           awk '/Object/{getline; print $1}')
19102         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
19103                           awk "/$objid = /"'{printf $3}')
19104
19105         echo $zfs_objid
19106 }
19107
19108 zfs_object_blksz() {
19109         local ost=$1
19110         local objid=$2
19111
19112         local vdevdir=$(dirname $(facet_vdevice $ost))
19113         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
19114         local blksz=$(do_facet $ost $cmd $objid |
19115                       awk '/dblk/{getline; printf $4}')
19116
19117         case "${blksz: -1}" in
19118                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
19119                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
19120                 *) ;;
19121         esac
19122
19123         echo $blksz
19124 }
19125
19126 test_312() { # LU-4856
19127         remote_ost_nodsh && skip "remote OST with nodsh"
19128         [ "$ost1_FSTYPE" = "zfs" ] ||
19129                 skip_env "the test only applies to zfs"
19130
19131         local max_blksz=$(do_facet ost1 \
19132                           $ZFS get -p recordsize $(facet_device ost1) |
19133                           awk '!/VALUE/{print $3}')
19134
19135         # to make life a little bit easier
19136         $LFS mkdir -c 1 -i 0 $DIR/$tdir
19137         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19138
19139         local tf=$DIR/$tdir/$tfile
19140         touch $tf
19141         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19142
19143         # Get ZFS object id
19144         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19145         # block size change by sequential overwrite
19146         local bs
19147
19148         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
19149                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
19150
19151                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
19152                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
19153         done
19154         rm -f $tf
19155
19156         # block size change by sequential append write
19157         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
19158         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19159         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19160         local count
19161
19162         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
19163                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
19164                         oflag=sync conv=notrunc
19165
19166                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
19167                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
19168                         error "blksz error, actual $blksz, " \
19169                                 "expected: 2 * $count * $PAGE_SIZE"
19170         done
19171         rm -f $tf
19172
19173         # random write
19174         touch $tf
19175         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19176         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19177
19178         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
19179         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19180         [ $blksz -eq $PAGE_SIZE ] ||
19181                 error "blksz error: $blksz, expected: $PAGE_SIZE"
19182
19183         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
19184         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19185         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
19186
19187         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
19188         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19189         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
19190 }
19191 run_test 312 "make sure ZFS adjusts its block size by write pattern"
19192
19193 test_313() {
19194         remote_ost_nodsh && skip "remote OST with nodsh"
19195
19196         local file=$DIR/$tfile
19197
19198         rm -f $file
19199         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
19200
19201         # define OBD_FAIL_TGT_RCVD_EIO           0x720
19202         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19203         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
19204                 error "write should failed"
19205         do_facet ost1 "$LCTL set_param fail_loc=0"
19206         rm -f $file
19207 }
19208 run_test 313 "io should fail after last_rcvd update fail"
19209
19210 test_314() {
19211         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19212
19213         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
19214         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19215         rm -f $DIR/$tfile
19216         wait_delete_completed
19217         do_facet ost1 "$LCTL set_param fail_loc=0"
19218 }
19219 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
19220
19221 test_315() { # LU-618
19222         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
19223
19224         local file=$DIR/$tfile
19225         rm -f $file
19226
19227         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
19228                 error "multiop file write failed"
19229         $MULTIOP $file oO_RDONLY:r4063232_c &
19230         PID=$!
19231
19232         sleep 2
19233
19234         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
19235         kill -USR1 $PID
19236
19237         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
19238         rm -f $file
19239 }
19240 run_test 315 "read should be accounted"
19241
19242 test_316() {
19243         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19244         large_xattr_enabled || skip_env "ea_inode feature disabled"
19245
19246         rm -rf $DIR/$tdir/d
19247         mkdir -p $DIR/$tdir/d
19248         chown nobody $DIR/$tdir/d
19249         touch $DIR/$tdir/d/file
19250
19251         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
19252 }
19253 run_test 316 "lfs mv"
19254
19255 test_317() {
19256         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
19257                 skip "Need MDS version at least 2.11.53"
19258         local trunc_sz
19259         local grant_blk_size
19260
19261         if [ "$(facet_fstype $facet)" == "zfs" ]; then
19262                 skip "LU-10370: no implementation for ZFS" && return
19263         fi
19264
19265         stack_trap "rm -f $DIR/$tfile" EXIT
19266         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
19267                         awk '/grant_block_size:/ { print $2; exit; }')
19268         #
19269         # Create File of size 5M. Truncate it to below size's and verify
19270         # blocks count.
19271         #
19272         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
19273                 error "Create file : $DIR/$tfile"
19274
19275         for trunc_sz in 2097152 4097 4000 509 0; do
19276                 $TRUNCATE $DIR/$tfile $trunc_sz ||
19277                         error "truncate $tfile to $trunc_sz failed"
19278                 local sz=$(stat --format=%s $DIR/$tfile)
19279                 local blk=$(stat --format=%b $DIR/$tfile)
19280                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
19281                                      grant_blk_size) * 8))
19282
19283                 if [[ $blk -ne $trunc_blk ]]; then
19284                         $(which stat) $DIR/$tfile
19285                         error "Expected Block $trunc_blk got $blk for $tfile"
19286                 fi
19287
19288                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19289                         error "Expected Size $trunc_sz got $sz for $tfile"
19290         done
19291
19292         #
19293         # sparse file test
19294         # Create file with a hole and write actual two blocks. Block count
19295         # must be 16.
19296         #
19297         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
19298                 conv=fsync || error "Create file : $DIR/$tfile"
19299
19300         # Calculate the final truncate size.
19301         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
19302
19303         #
19304         # truncate to size $trunc_sz bytes. Strip the last block
19305         # The block count must drop to 8
19306         #
19307         $TRUNCATE $DIR/$tfile $trunc_sz ||
19308                 error "truncate $tfile to $trunc_sz failed"
19309
19310         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
19311         sz=$(stat --format=%s $DIR/$tfile)
19312         blk=$(stat --format=%b $DIR/$tfile)
19313
19314         if [[ $blk -ne $trunc_bsz ]]; then
19315                 $(which stat) $DIR/$tfile
19316                 error "Expected Block $trunc_bsz got $blk for $tfile"
19317         fi
19318
19319         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19320                 error "Expected Size $trunc_sz got $sz for $tfile"
19321 }
19322 run_test 317 "Verify blocks get correctly update after truncate"
19323
19324 test_318() {
19325         local old_max_active=$($LCTL get_param -n \
19326                             llite.*.max_read_ahead_async_active 2>/dev/null)
19327
19328         $LCTL set_param llite.*.max_read_ahead_async_active=256
19329         local max_active=$($LCTL get_param -n \
19330                            llite.*.max_read_ahead_async_active 2>/dev/null)
19331         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
19332
19333         # currently reset to 0 is unsupported, leave it 512 for now.
19334         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
19335                 error "set max_read_ahead_async_active should fail"
19336
19337         $LCTL set_param llite.*.max_read_ahead_async_active=512
19338         max_active=$($LCTL get_param -n \
19339                      llite.*.max_read_ahead_async_active 2>/dev/null)
19340         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
19341
19342         # restore @max_active
19343         [ $old_max_active -ne 0 ] && $LCTL set_param \
19344                 llite.*.max_read_ahead_async_active=$old_max_active
19345
19346         local old_threshold=$($LCTL get_param -n \
19347                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19348         local max_per_file_mb=$($LCTL get_param -n \
19349                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
19350
19351         local invalid=$(($max_per_file_mb + 1))
19352         $LCTL set_param \
19353                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
19354                         && error "set $invalid should fail"
19355
19356         local valid=$(($invalid - 1))
19357         $LCTL set_param \
19358                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
19359                         error "set $valid should succeed"
19360         local threshold=$($LCTL get_param -n \
19361                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19362         [ $threshold -eq $valid ] || error \
19363                 "expect threshold $valid got $threshold"
19364         $LCTL set_param \
19365                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
19366 }
19367 run_test 318 "Verify async readahead tunables"
19368
19369 test_319() {
19370         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
19371
19372         local before=$(date +%s)
19373         local evict
19374         local mdir=$DIR/$tdir
19375         local file=$mdir/xxx
19376
19377         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
19378         touch $file
19379
19380 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
19381         $LCTL set_param fail_val=5 fail_loc=0x8000032c
19382         $LFS mv -m1 $file &
19383
19384         sleep 1
19385         dd if=$file of=/dev/null
19386         wait
19387         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
19388           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
19389
19390         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
19391 }
19392 run_test 319 "lost lease lock on migrate error"
19393
19394 test_fake_rw() {
19395         local read_write=$1
19396         if [ "$read_write" = "write" ]; then
19397                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
19398         elif [ "$read_write" = "read" ]; then
19399                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
19400         else
19401                 error "argument error"
19402         fi
19403
19404         # turn off debug for performance testing
19405         local saved_debug=$($LCTL get_param -n debug)
19406         $LCTL set_param debug=0
19407
19408         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19409
19410         # get ost1 size - lustre-OST0000
19411         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
19412         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
19413         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
19414
19415         if [ "$read_write" = "read" ]; then
19416                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
19417         fi
19418
19419         local start_time=$(date +%s.%N)
19420         $dd_cmd bs=1M count=$blocks oflag=sync ||
19421                 error "real dd $read_write error"
19422         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
19423
19424         if [ "$read_write" = "write" ]; then
19425                 rm -f $DIR/$tfile
19426         fi
19427
19428         # define OBD_FAIL_OST_FAKE_RW           0x238
19429         do_facet ost1 $LCTL set_param fail_loc=0x238
19430
19431         local start_time=$(date +%s.%N)
19432         $dd_cmd bs=1M count=$blocks oflag=sync ||
19433                 error "fake dd $read_write error"
19434         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
19435
19436         if [ "$read_write" = "write" ]; then
19437                 # verify file size
19438                 cancel_lru_locks osc
19439                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
19440                         error "$tfile size not $blocks MB"
19441         fi
19442         do_facet ost1 $LCTL set_param fail_loc=0
19443
19444         echo "fake $read_write $duration_fake vs. normal $read_write" \
19445                 "$duration in seconds"
19446         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
19447                 error_not_in_vm "fake write is slower"
19448
19449         $LCTL set_param -n debug="$saved_debug"
19450         rm -f $DIR/$tfile
19451 }
19452 test_399a() { # LU-7655 for OST fake write
19453         remote_ost_nodsh && skip "remote OST with nodsh"
19454
19455         test_fake_rw write
19456 }
19457 run_test 399a "fake write should not be slower than normal write"
19458
19459 test_399b() { # LU-8726 for OST fake read
19460         remote_ost_nodsh && skip "remote OST with nodsh"
19461         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
19462                 skip_env "ldiskfs only test"
19463         fi
19464
19465         test_fake_rw read
19466 }
19467 run_test 399b "fake read should not be slower than normal read"
19468
19469 test_400a() { # LU-1606, was conf-sanity test_74
19470         if ! which $CC > /dev/null 2>&1; then
19471                 skip_env "$CC is not installed"
19472         fi
19473
19474         local extra_flags=''
19475         local out=$TMP/$tfile
19476         local prefix=/usr/include/lustre
19477         local prog
19478
19479         if ! [[ -d $prefix ]]; then
19480                 # Assume we're running in tree and fixup the include path.
19481                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19482                 extra_flags+=" -L$LUSTRE/utils/.lib"
19483         fi
19484
19485         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19486                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19487                         error "client api broken"
19488         done
19489         rm -f $out
19490 }
19491 run_test 400a "Lustre client api program can compile and link"
19492
19493 test_400b() { # LU-1606, LU-5011
19494         local header
19495         local out=$TMP/$tfile
19496         local prefix=/usr/include/linux/lustre
19497
19498         # We use a hard coded prefix so that this test will not fail
19499         # when run in tree. There are headers in lustre/include/lustre/
19500         # that are not packaged (like lustre_idl.h) and have more
19501         # complicated include dependencies (like config.h and lnet/types.h).
19502         # Since this test about correct packaging we just skip them when
19503         # they don't exist (see below) rather than try to fixup cppflags.
19504
19505         if ! which $CC > /dev/null 2>&1; then
19506                 skip_env "$CC is not installed"
19507         fi
19508
19509         for header in $prefix/*.h; do
19510                 if ! [[ -f "$header" ]]; then
19511                         continue
19512                 fi
19513
19514                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19515                         continue # lustre_ioctl.h is internal header
19516                 fi
19517
19518                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19519                         error "cannot compile '$header'"
19520         done
19521         rm -f $out
19522 }
19523 run_test 400b "packaged headers can be compiled"
19524
19525 test_401a() { #LU-7437
19526         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19527         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19528
19529         #count the number of parameters by "list_param -R"
19530         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19531         #count the number of parameters by listing proc files
19532         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19533         echo "proc_dirs='$proc_dirs'"
19534         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19535         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19536                       sort -u | wc -l)
19537
19538         [ $params -eq $procs ] ||
19539                 error "found $params parameters vs. $procs proc files"
19540
19541         # test the list_param -D option only returns directories
19542         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19543         #count the number of parameters by listing proc directories
19544         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19545                 sort -u | wc -l)
19546
19547         [ $params -eq $procs ] ||
19548                 error "found $params parameters vs. $procs proc files"
19549 }
19550 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19551
19552 test_401b() {
19553         local save=$($LCTL get_param -n jobid_var)
19554         local tmp=testing
19555
19556         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19557                 error "no error returned when setting bad parameters"
19558
19559         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19560         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19561
19562         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19563         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19564         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19565 }
19566 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19567
19568 test_401c() {
19569         local jobid_var_old=$($LCTL get_param -n jobid_var)
19570         local jobid_var_new
19571
19572         $LCTL set_param jobid_var= &&
19573                 error "no error returned for 'set_param a='"
19574
19575         jobid_var_new=$($LCTL get_param -n jobid_var)
19576         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19577                 error "jobid_var was changed by setting without value"
19578
19579         $LCTL set_param jobid_var &&
19580                 error "no error returned for 'set_param a'"
19581
19582         jobid_var_new=$($LCTL get_param -n jobid_var)
19583         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19584                 error "jobid_var was changed by setting without value"
19585 }
19586 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19587
19588 test_401d() {
19589         local jobid_var_old=$($LCTL get_param -n jobid_var)
19590         local jobid_var_new
19591         local new_value="foo=bar"
19592
19593         $LCTL set_param jobid_var=$new_value ||
19594                 error "'set_param a=b' did not accept a value containing '='"
19595
19596         jobid_var_new=$($LCTL get_param -n jobid_var)
19597         [[ "$jobid_var_new" == "$new_value" ]] ||
19598                 error "'set_param a=b' failed on a value containing '='"
19599
19600         # Reset the jobid_var to test the other format
19601         $LCTL set_param jobid_var=$jobid_var_old
19602         jobid_var_new=$($LCTL get_param -n jobid_var)
19603         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19604                 error "failed to reset jobid_var"
19605
19606         $LCTL set_param jobid_var $new_value ||
19607                 error "'set_param a b' did not accept a value containing '='"
19608
19609         jobid_var_new=$($LCTL get_param -n jobid_var)
19610         [[ "$jobid_var_new" == "$new_value" ]] ||
19611                 error "'set_param a b' failed on a value containing '='"
19612
19613         $LCTL set_param jobid_var $jobid_var_old
19614         jobid_var_new=$($LCTL get_param -n jobid_var)
19615         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19616                 error "failed to reset jobid_var"
19617 }
19618 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19619
19620 test_402() {
19621         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19622         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19623                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19624         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19625                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19626                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19627         remote_mds_nodsh && skip "remote MDS with nodsh"
19628
19629         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19630 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19631         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19632         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19633                 echo "Touch failed - OK"
19634 }
19635 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19636
19637 test_403() {
19638         local file1=$DIR/$tfile.1
19639         local file2=$DIR/$tfile.2
19640         local tfile=$TMP/$tfile
19641
19642         rm -f $file1 $file2 $tfile
19643
19644         touch $file1
19645         ln $file1 $file2
19646
19647         # 30 sec OBD_TIMEOUT in ll_getattr()
19648         # right before populating st_nlink
19649         $LCTL set_param fail_loc=0x80001409
19650         stat -c %h $file1 > $tfile &
19651
19652         # create an alias, drop all locks and reclaim the dentry
19653         < $file2
19654         cancel_lru_locks mdc
19655         cancel_lru_locks osc
19656         sysctl -w vm.drop_caches=2
19657
19658         wait
19659
19660         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19661
19662         rm -f $tfile $file1 $file2
19663 }
19664 run_test 403 "i_nlink should not drop to zero due to aliasing"
19665
19666 test_404() { # LU-6601
19667         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19668                 skip "Need server version newer than 2.8.52"
19669         remote_mds_nodsh && skip "remote MDS with nodsh"
19670
19671         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19672                 awk '/osp .*-osc-MDT/ { print $4}')
19673
19674         local osp
19675         for osp in $mosps; do
19676                 echo "Deactivate: " $osp
19677                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19678                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19679                         awk -vp=$osp '$4 == p { print $2 }')
19680                 [ $stat = IN ] || {
19681                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19682                         error "deactivate error"
19683                 }
19684                 echo "Activate: " $osp
19685                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19686                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19687                         awk -vp=$osp '$4 == p { print $2 }')
19688                 [ $stat = UP ] || {
19689                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19690                         error "activate error"
19691                 }
19692         done
19693 }
19694 run_test 404 "validate manual {de}activated works properly for OSPs"
19695
19696 test_405() {
19697         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19698         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19699                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19700                         skip "Layout swap lock is not supported"
19701
19702         check_swap_layouts_support
19703
19704         test_mkdir $DIR/$tdir
19705         swap_lock_test -d $DIR/$tdir ||
19706                 error "One layout swap locked test failed"
19707 }
19708 run_test 405 "Various layout swap lock tests"
19709
19710 test_406() {
19711         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19712         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19713         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19715         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19716                 skip "Need MDS version at least 2.8.50"
19717
19718         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19719         local test_pool=$TESTNAME
19720
19721         if ! combined_mgs_mds ; then
19722                 mount_mgs_client
19723         fi
19724         pool_add $test_pool || error "pool_add failed"
19725         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19726                 error "pool_add_targets failed"
19727
19728         save_layout_restore_at_exit $MOUNT
19729
19730         # parent set default stripe count only, child will stripe from both
19731         # parent and fs default
19732         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19733                 error "setstripe $MOUNT failed"
19734         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19735         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19736         for i in $(seq 10); do
19737                 local f=$DIR/$tdir/$tfile.$i
19738                 touch $f || error "touch failed"
19739                 local count=$($LFS getstripe -c $f)
19740                 [ $count -eq $OSTCOUNT ] ||
19741                         error "$f stripe count $count != $OSTCOUNT"
19742                 local offset=$($LFS getstripe -i $f)
19743                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19744                 local size=$($LFS getstripe -S $f)
19745                 [ $size -eq $((def_stripe_size * 2)) ] ||
19746                         error "$f stripe size $size != $((def_stripe_size * 2))"
19747                 local pool=$($LFS getstripe -p $f)
19748                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19749         done
19750
19751         # change fs default striping, delete parent default striping, now child
19752         # will stripe from new fs default striping only
19753         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19754                 error "change $MOUNT default stripe failed"
19755         $LFS setstripe -c 0 $DIR/$tdir ||
19756                 error "delete $tdir default stripe failed"
19757         for i in $(seq 11 20); do
19758                 local f=$DIR/$tdir/$tfile.$i
19759                 touch $f || error "touch $f failed"
19760                 local count=$($LFS getstripe -c $f)
19761                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19762                 local offset=$($LFS getstripe -i $f)
19763                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19764                 local size=$($LFS getstripe -S $f)
19765                 [ $size -eq $def_stripe_size ] ||
19766                         error "$f stripe size $size != $def_stripe_size"
19767                 local pool=$($LFS getstripe -p $f)
19768                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19769         done
19770
19771         unlinkmany $DIR/$tdir/$tfile. 1 20
19772
19773         local f=$DIR/$tdir/$tfile
19774         pool_remove_all_targets $test_pool $f
19775         pool_remove $test_pool $f
19776
19777         if ! combined_mgs_mds ; then
19778                 umount_mgs_client
19779         fi
19780 }
19781 run_test 406 "DNE support fs default striping"
19782
19783 test_407() {
19784         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19785         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19786                 skip "Need MDS version at least 2.8.55"
19787         remote_mds_nodsh && skip "remote MDS with nodsh"
19788
19789         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19790                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19791         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19792                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19793         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19794
19795         #define OBD_FAIL_DT_TXN_STOP    0x2019
19796         for idx in $(seq $MDSCOUNT); do
19797                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19798         done
19799         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19800         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19801                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19802         true
19803 }
19804 run_test 407 "transaction fail should cause operation fail"
19805
19806 test_408() {
19807         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19808
19809         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19810         lctl set_param fail_loc=0x8000040a
19811         # let ll_prepare_partial_page() fail
19812         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19813
19814         rm -f $DIR/$tfile
19815
19816         # create at least 100 unused inodes so that
19817         # shrink_icache_memory(0) should not return 0
19818         touch $DIR/$tfile-{0..100}
19819         rm -f $DIR/$tfile-{0..100}
19820         sync
19821
19822         echo 2 > /proc/sys/vm/drop_caches
19823 }
19824 run_test 408 "drop_caches should not hang due to page leaks"
19825
19826 test_409()
19827 {
19828         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19829
19830         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19831         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19832         touch $DIR/$tdir/guard || error "(2) Fail to create"
19833
19834         local PREFIX=$(str_repeat 'A' 128)
19835         echo "Create 1K hard links start at $(date)"
19836         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19837                 error "(3) Fail to hard link"
19838
19839         echo "Links count should be right although linkEA overflow"
19840         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19841         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19842         [ $linkcount -eq 1001 ] ||
19843                 error "(5) Unexpected hard links count: $linkcount"
19844
19845         echo "List all links start at $(date)"
19846         ls -l $DIR/$tdir/foo > /dev/null ||
19847                 error "(6) Fail to list $DIR/$tdir/foo"
19848
19849         echo "Unlink hard links start at $(date)"
19850         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19851                 error "(7) Fail to unlink"
19852         echo "Unlink hard links finished at $(date)"
19853 }
19854 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19855
19856 test_410()
19857 {
19858         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19859                 skip "Need client version at least 2.9.59"
19860
19861         # Create a file, and stat it from the kernel
19862         local testfile=$DIR/$tfile
19863         touch $testfile
19864
19865         local run_id=$RANDOM
19866         local my_ino=$(stat --format "%i" $testfile)
19867
19868         # Try to insert the module. This will always fail as the
19869         # module is designed to not be inserted.
19870         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19871             &> /dev/null
19872
19873         # Anything but success is a test failure
19874         dmesg | grep -q \
19875             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19876             error "no inode match"
19877 }
19878 run_test 410 "Test inode number returned from kernel thread"
19879
19880 cleanup_test411_cgroup() {
19881         trap 0
19882         rmdir "$1"
19883 }
19884
19885 test_411() {
19886         local cg_basedir=/sys/fs/cgroup/memory
19887         # LU-9966
19888         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19889                 skip "no setup for cgroup"
19890
19891         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19892                 error "test file creation failed"
19893         cancel_lru_locks osc
19894
19895         # Create a very small memory cgroup to force a slab allocation error
19896         local cgdir=$cg_basedir/osc_slab_alloc
19897         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19898         trap "cleanup_test411_cgroup $cgdir" EXIT
19899         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19900         echo 1M > $cgdir/memory.limit_in_bytes
19901
19902         # Should not LBUG, just be killed by oom-killer
19903         # dd will return 0 even allocation failure in some environment.
19904         # So don't check return value
19905         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19906         cleanup_test411_cgroup $cgdir
19907
19908         return 0
19909 }
19910 run_test 411 "Slab allocation error with cgroup does not LBUG"
19911
19912 test_412() {
19913         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19914         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19915                 skip "Need server version at least 2.10.55"
19916         fi
19917
19918         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19919                 error "mkdir failed"
19920         $LFS getdirstripe $DIR/$tdir
19921         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19922         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19923                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19924         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19925         [ $stripe_count -eq 2 ] ||
19926                 error "expect 2 get $stripe_count"
19927 }
19928 run_test 412 "mkdir on specific MDTs"
19929
19930 test_413a() {
19931         [ $MDSCOUNT -lt 2 ] &&
19932                 skip "We need at least 2 MDTs for this test"
19933
19934         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19935                 skip "Need server version at least 2.10.55"
19936         fi
19937
19938         mkdir $DIR/$tdir || error "mkdir failed"
19939
19940         # find MDT that is the most full
19941         local max=$($LFS df | grep MDT |
19942                 awk 'BEGIN { a=0 }
19943                         { sub("%", "", $5)
19944                           if (0+$5 >= a)
19945                           {
19946                                 a = $5
19947                                 b = $6
19948                           }
19949                         }
19950                      END { split(b, c, ":")
19951                            sub("]", "", c[2])
19952                            print c[2]
19953                          }')
19954
19955         for i in $(seq $((MDSCOUNT - 1))); do
19956                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19957                         error "mkdir d$i failed"
19958                 $LFS getdirstripe $DIR/$tdir/d$i
19959                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19960                 [ $stripe_index -ne $max ] ||
19961                         error "don't expect $max"
19962         done
19963 }
19964 run_test 413a "mkdir on less full MDTs"
19965
19966 test_413b() {
19967         [ $MDSCOUNT -lt 2 ] &&
19968                 skip "We need at least 2 MDTs for this test"
19969
19970         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
19971                 skip "Need server version at least 2.12.52"
19972
19973         mkdir $DIR/$tdir || error "mkdir failed"
19974         $LFS setdirstripe -D -i -1 -H space $DIR/$tdir ||
19975                 error "setdirstripe failed"
19976
19977         local qos_prio_free
19978         local qos_threshold_rr
19979         local count
19980
19981         qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
19982         qos_prio_free=${qos_prio_free%%%}
19983         qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr | head -n1)
19984         qos_threshold_rr=${qos_threshold_rr%%%}
19985
19986         stack_trap "$LCTL set_param lmv.*.qos_prio_free=$qos_prio_free" EXIT
19987         stack_trap "$LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr" \
19988                 EXIT
19989
19990         echo "mkdir with roundrobin"
19991
19992         $LCTL set_param lmv.*.qos_threshold_rr=100
19993         for i in $(seq $((100 * MDSCOUNT))); do
19994                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
19995         done
19996         for i in $(seq $MDSCOUNT); do
19997                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
19998                         wc -w)
19999                 echo "$count directories created on MDT$((i - 1))"
20000                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
20001         done
20002
20003         rm -rf $DIR/$tdir/*
20004
20005         $LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr
20006
20007         local ffree
20008         local max
20009         local min
20010         local max_index
20011         local min_index
20012
20013         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree | uniq))
20014         echo "MDT filesfree available: ${ffree[@]}"
20015         max=${ffree[0]}
20016         min=${ffree[0]}
20017         max_index=0
20018         min_index=0
20019         for ((i = 0; i < ${#ffree[@]}; i++)); do
20020                 if [[ ${ffree[i]} -gt $max ]]; then
20021                         max=${ffree[i]}
20022                         max_index=$i
20023                 fi
20024                 if [[ ${ffree[i]} -lt $min ]]; then
20025                         min=${ffree[i]}
20026                         min_index=$i
20027                 fi
20028         done
20029         echo "Min free files: MDT$min_index: $min"
20030         echo "Max free files: MDT$max_index: $max"
20031
20032         [ $min -eq 0 ] && skip "no free files in MDT$min_index"
20033         [ $min -gt 10000000 ] && skip "too much free files in MDT$min_index"
20034
20035         # Check if we need to generate uneven MDTs
20036         test_mkdir -i $min_index -c 1 -p $DIR/$tdir-MDT$min_index
20037         local threshold=10
20038         local diff=$((max - min))
20039         local diff2=$((diff * 100 / min))
20040
20041         echo -n "Check for uneven MDTs: "
20042         echo -n "diff=$diff files ($diff2%) must be > $threshold% ..."
20043
20044         if [ $diff2 -gt $threshold ]; then
20045                 echo "ok"
20046                 echo "Don't need to fill MDT$min_index"
20047         else
20048                 # generate uneven MDTs, create till 25% diff
20049                 echo "no"
20050                 diff2=$((threshold - diff2))
20051                 diff=$((min * diff2 / 100))
20052                 # 50 sec per 10000 files in vm
20053                 [ $diff -gt 40000 ] && [ "$SLOW" = "no" ] &&
20054                         skip "$diff files to create"
20055                 echo "Fill $diff2% diff in MDT$min_index with $diff files"
20056                 local i
20057                 local value="$(generate_string 1024)"
20058                 for i in $(seq $diff); do
20059                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
20060                                 $DIR/$tdir-MDT$min_index/f$i > /dev/null ||
20061                                 error "create f$i failed"
20062                         setfattr -n user.413b -v $value \
20063                                 $DIR/$tdir-MDT$min_index/f$i ||
20064                                 error "setfattr f$i failed"
20065                 done
20066         fi
20067
20068         min=$((100 *MDSCOUNT))
20069         max=0
20070
20071         echo "mkdir with balanced space usage"
20072         $LCTL set_param lmv.*.qos_prio_free=100
20073         for i in $(seq $((100 * MDSCOUNT))); do
20074                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20075         done
20076         for i in $(seq $MDSCOUNT); do
20077                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20078                         wc -w)
20079                 echo "$count directories created on MDT$((i - 1))"
20080                 [ $min -gt $count ] && min=$count
20081                 [ $max -lt $count ] && max=$count
20082         done
20083         [ $((max - min)) -gt $MDSCOUNT ] ||
20084                 error "subdirs shouldn't be evenly distributed"
20085
20086         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20087
20088         $LFS setdirstripe -D -d $DIR/$tdir || error "setdirstripe -d failed"
20089         getfattr -n trusted.dmv $DIR/$tdir && error "default dir layout exists"
20090         true
20091 }
20092 run_test 413b "mkdir with balanced space usage"
20093
20094 test_414() {
20095 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
20096         $LCTL set_param fail_loc=0x80000521
20097         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
20098         rm -f $DIR/$tfile
20099 }
20100 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
20101
20102 test_415() {
20103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20104         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
20105                 skip "Need server version at least 2.11.52"
20106
20107         # LU-11102
20108         local total
20109         local setattr_pid
20110         local start_time
20111         local end_time
20112         local duration
20113
20114         total=500
20115         # this test may be slow on ZFS
20116         [ "$mds1_FSTYPE" == "zfs" ] && total=100
20117
20118         # though this test is designed for striped directory, let's test normal
20119         # directory too since lock is always saved as CoS lock.
20120         test_mkdir $DIR/$tdir || error "mkdir $tdir"
20121         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
20122
20123         (
20124                 while true; do
20125                         touch $DIR/$tdir
20126                 done
20127         ) &
20128         setattr_pid=$!
20129
20130         start_time=$(date +%s)
20131         for i in $(seq $total); do
20132                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
20133                         > /dev/null
20134         done
20135         end_time=$(date +%s)
20136         duration=$((end_time - start_time))
20137
20138         kill -9 $setattr_pid
20139
20140         echo "rename $total files took $duration sec"
20141         [ $duration -lt 100 ] || error "rename took $duration sec"
20142 }
20143 run_test 415 "lock revoke is not missing"
20144
20145 test_416() {
20146         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
20147                 skip "Need server version at least 2.11.55"
20148
20149         # define OBD_FAIL_OSD_TXN_START    0x19a
20150         do_facet mds1 lctl set_param fail_loc=0x19a
20151
20152         lfs mkdir -c $MDSCOUNT $DIR/$tdir
20153
20154         true
20155 }
20156 run_test 416 "transaction start failure won't cause system hung"
20157
20158 cleanup_417() {
20159         trap 0
20160         do_nodes $(comma_list $(mdts_nodes)) \
20161                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
20162         do_nodes $(comma_list $(mdts_nodes)) \
20163                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
20164         do_nodes $(comma_list $(mdts_nodes)) \
20165                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
20166 }
20167
20168 test_417() {
20169         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20170         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
20171                 skip "Need MDS version at least 2.11.56"
20172
20173         trap cleanup_417 RETURN EXIT
20174
20175         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
20176         do_nodes $(comma_list $(mdts_nodes)) \
20177                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
20178         $LFS migrate -m 0 $DIR/$tdir.1 &&
20179                 error "migrate dir $tdir.1 should fail"
20180
20181         do_nodes $(comma_list $(mdts_nodes)) \
20182                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
20183         $LFS mkdir -i 1 $DIR/$tdir.2 &&
20184                 error "create remote dir $tdir.2 should fail"
20185
20186         do_nodes $(comma_list $(mdts_nodes)) \
20187                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
20188         $LFS mkdir -c 2 $DIR/$tdir.3 &&
20189                 error "create striped dir $tdir.3 should fail"
20190         true
20191 }
20192 run_test 417 "disable remote dir, striped dir and dir migration"
20193
20194 # Checks that the outputs of df [-i] and lfs df [-i] match
20195 #
20196 # usage: check_lfs_df <blocks | inodes> <mountpoint>
20197 check_lfs_df() {
20198         local dir=$2
20199         local inodes
20200         local df_out
20201         local lfs_df_out
20202         local count
20203         local passed=false
20204
20205         # blocks or inodes
20206         [ "$1" == "blocks" ] && inodes= || inodes="-i"
20207
20208         for count in {1..100}; do
20209                 cancel_lru_locks
20210                 sync; sleep 0.2
20211
20212                 # read the lines of interest
20213                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
20214                         error "df $inodes $dir | tail -n +2 failed"
20215                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
20216                         error "lfs df $inodes $dir | grep summary: failed"
20217
20218                 # skip first substrings of each output as they are different
20219                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
20220                 # compare the two outputs
20221                 passed=true
20222                 for i in {1..5}; do
20223                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
20224                 done
20225                 $passed && break
20226         done
20227
20228         if ! $passed; then
20229                 df -P $inodes $dir
20230                 echo
20231                 lfs df $inodes $dir
20232                 error "df and lfs df $1 output mismatch: "      \
20233                       "df ${inodes}: ${df_out[*]}, "            \
20234                       "lfs df ${inodes}: ${lfs_df_out[*]}"
20235         fi
20236 }
20237
20238 test_418() {
20239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20240
20241         local dir=$DIR/$tdir
20242         local numfiles=$((RANDOM % 4096 + 2))
20243         local numblocks=$((RANDOM % 256 + 1))
20244
20245         wait_delete_completed
20246         test_mkdir $dir
20247
20248         # check block output
20249         check_lfs_df blocks $dir
20250         # check inode output
20251         check_lfs_df inodes $dir
20252
20253         # create a single file and retest
20254         echo "Creating a single file and testing"
20255         createmany -o $dir/$tfile- 1 &>/dev/null ||
20256                 error "creating 1 file in $dir failed"
20257         check_lfs_df blocks $dir
20258         check_lfs_df inodes $dir
20259
20260         # create a random number of files
20261         echo "Creating $((numfiles - 1)) files and testing"
20262         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
20263                 error "creating $((numfiles - 1)) files in $dir failed"
20264
20265         # write a random number of blocks to the first test file
20266         echo "Writing $numblocks 4K blocks and testing"
20267         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
20268                 count=$numblocks &>/dev/null ||
20269                 error "dd to $dir/${tfile}-0 failed"
20270
20271         # retest
20272         check_lfs_df blocks $dir
20273         check_lfs_df inodes $dir
20274
20275         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
20276                 error "unlinking $numfiles files in $dir failed"
20277 }
20278 run_test 418 "df and lfs df outputs match"
20279
20280 test_419()
20281 {
20282         local dir=$DIR/$tdir
20283
20284         mkdir -p $dir
20285         touch $dir/file
20286
20287         cancel_lru_locks mdc
20288
20289         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
20290         $LCTL set_param fail_loc=0x1410
20291         cat $dir/file
20292         $LCTL set_param fail_loc=0
20293         rm -rf $dir
20294 }
20295 run_test 419 "Verify open file by name doesn't crash kernel"
20296
20297 test_420()
20298 {
20299         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
20300                 skip "Need MDS version at least 2.12.53"
20301
20302         local SAVE_UMASK=$(umask)
20303         local dir=$DIR/$tdir
20304         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
20305
20306         mkdir -p $dir
20307         umask 0000
20308         mkdir -m03777 $dir/testdir
20309         ls -dn $dir/testdir
20310         # Need to remove trailing '.' when SELinux is enabled
20311         local dirperms=$(ls -dn $dir/testdir |
20312                          awk '{ sub(/\.$/, "", $1); print $1}')
20313         [ $dirperms == "drwxrwsrwt" ] ||
20314                 error "incorrect perms on $dir/testdir"
20315
20316         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
20317                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
20318         ls -n $dir/testdir/testfile
20319         local fileperms=$(ls -n $dir/testdir/testfile |
20320                           awk '{ sub(/\.$/, "", $1); print $1}')
20321         [ $fileperms == "-rwxr-xr-x" ] ||
20322                 error "incorrect perms on $dir/testdir/testfile"
20323
20324         umask $SAVE_UMASK
20325 }
20326 run_test 420 "clear SGID bit on non-directories for non-members"
20327
20328 prep_801() {
20329         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20330         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20331                 skip "Need server version at least 2.9.55"
20332
20333         start_full_debug_logging
20334 }
20335
20336 post_801() {
20337         stop_full_debug_logging
20338 }
20339
20340 barrier_stat() {
20341         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20342                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20343                            awk '/The barrier for/ { print $7 }')
20344                 echo $st
20345         else
20346                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
20347                 echo \'$st\'
20348         fi
20349 }
20350
20351 barrier_expired() {
20352         local expired
20353
20354         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20355                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20356                           awk '/will be expired/ { print $7 }')
20357         else
20358                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
20359         fi
20360
20361         echo $expired
20362 }
20363
20364 test_801a() {
20365         prep_801
20366
20367         echo "Start barrier_freeze at: $(date)"
20368         #define OBD_FAIL_BARRIER_DELAY          0x2202
20369         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20370         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
20371
20372         sleep 2
20373         local b_status=$(barrier_stat)
20374         echo "Got barrier status at: $(date)"
20375         [ "$b_status" = "'freezing_p1'" ] ||
20376                 error "(1) unexpected barrier status $b_status"
20377
20378         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20379         wait
20380         b_status=$(barrier_stat)
20381         [ "$b_status" = "'frozen'" ] ||
20382                 error "(2) unexpected barrier status $b_status"
20383
20384         local expired=$(barrier_expired)
20385         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
20386         sleep $((expired + 3))
20387
20388         b_status=$(barrier_stat)
20389         [ "$b_status" = "'expired'" ] ||
20390                 error "(3) unexpected barrier status $b_status"
20391
20392         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
20393                 error "(4) fail to freeze barrier"
20394
20395         b_status=$(barrier_stat)
20396         [ "$b_status" = "'frozen'" ] ||
20397                 error "(5) unexpected barrier status $b_status"
20398
20399         echo "Start barrier_thaw at: $(date)"
20400         #define OBD_FAIL_BARRIER_DELAY          0x2202
20401         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20402         do_facet mgs $LCTL barrier_thaw $FSNAME &
20403
20404         sleep 2
20405         b_status=$(barrier_stat)
20406         echo "Got barrier status at: $(date)"
20407         [ "$b_status" = "'thawing'" ] ||
20408                 error "(6) unexpected barrier status $b_status"
20409
20410         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20411         wait
20412         b_status=$(barrier_stat)
20413         [ "$b_status" = "'thawed'" ] ||
20414                 error "(7) unexpected barrier status $b_status"
20415
20416         #define OBD_FAIL_BARRIER_FAILURE        0x2203
20417         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
20418         do_facet mgs $LCTL barrier_freeze $FSNAME
20419
20420         b_status=$(barrier_stat)
20421         [ "$b_status" = "'failed'" ] ||
20422                 error "(8) unexpected barrier status $b_status"
20423
20424         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20425         do_facet mgs $LCTL barrier_thaw $FSNAME
20426
20427         post_801
20428 }
20429 run_test 801a "write barrier user interfaces and stat machine"
20430
20431 test_801b() {
20432         prep_801
20433
20434         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20435         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
20436         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
20437         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
20438         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
20439
20440         cancel_lru_locks mdc
20441
20442         # 180 seconds should be long enough
20443         do_facet mgs $LCTL barrier_freeze $FSNAME 180
20444
20445         local b_status=$(barrier_stat)
20446         [ "$b_status" = "'frozen'" ] ||
20447                 error "(6) unexpected barrier status $b_status"
20448
20449         mkdir $DIR/$tdir/d0/d10 &
20450         mkdir_pid=$!
20451
20452         touch $DIR/$tdir/d1/f13 &
20453         touch_pid=$!
20454
20455         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
20456         ln_pid=$!
20457
20458         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
20459         mv_pid=$!
20460
20461         rm -f $DIR/$tdir/d4/f12 &
20462         rm_pid=$!
20463
20464         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
20465
20466         # To guarantee taht the 'stat' is not blocked
20467         b_status=$(barrier_stat)
20468         [ "$b_status" = "'frozen'" ] ||
20469                 error "(8) unexpected barrier status $b_status"
20470
20471         # let above commands to run at background
20472         sleep 5
20473
20474         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
20475         ps -p $touch_pid || error "(10) touch should be blocked"
20476         ps -p $ln_pid || error "(11) link should be blocked"
20477         ps -p $mv_pid || error "(12) rename should be blocked"
20478         ps -p $rm_pid || error "(13) unlink should be blocked"
20479
20480         b_status=$(barrier_stat)
20481         [ "$b_status" = "'frozen'" ] ||
20482                 error "(14) unexpected barrier status $b_status"
20483
20484         do_facet mgs $LCTL barrier_thaw $FSNAME
20485         b_status=$(barrier_stat)
20486         [ "$b_status" = "'thawed'" ] ||
20487                 error "(15) unexpected barrier status $b_status"
20488
20489         wait $mkdir_pid || error "(16) mkdir should succeed"
20490         wait $touch_pid || error "(17) touch should succeed"
20491         wait $ln_pid || error "(18) link should succeed"
20492         wait $mv_pid || error "(19) rename should succeed"
20493         wait $rm_pid || error "(20) unlink should succeed"
20494
20495         post_801
20496 }
20497 run_test 801b "modification will be blocked by write barrier"
20498
20499 test_801c() {
20500         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20501
20502         prep_801
20503
20504         stop mds2 || error "(1) Fail to stop mds2"
20505
20506         do_facet mgs $LCTL barrier_freeze $FSNAME 30
20507
20508         local b_status=$(barrier_stat)
20509         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
20510                 do_facet mgs $LCTL barrier_thaw $FSNAME
20511                 error "(2) unexpected barrier status $b_status"
20512         }
20513
20514         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20515                 error "(3) Fail to rescan barrier bitmap"
20516
20517         do_facet mgs $LCTL barrier_freeze $FSNAME 10
20518
20519         b_status=$(barrier_stat)
20520         [ "$b_status" = "'frozen'" ] ||
20521                 error "(4) unexpected barrier status $b_status"
20522
20523         do_facet mgs $LCTL barrier_thaw $FSNAME
20524         b_status=$(barrier_stat)
20525         [ "$b_status" = "'thawed'" ] ||
20526                 error "(5) unexpected barrier status $b_status"
20527
20528         local devname=$(mdsdevname 2)
20529
20530         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
20531
20532         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20533                 error "(7) Fail to rescan barrier bitmap"
20534
20535         post_801
20536 }
20537 run_test 801c "rescan barrier bitmap"
20538
20539 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
20540 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
20541 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
20542
20543 cleanup_802a() {
20544         trap 0
20545
20546         stopall
20547         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
20548         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
20549         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
20550         setupall
20551 }
20552
20553 test_802a() {
20554
20555         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20556         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20557                 skip "Need server version at least 2.9.55"
20558
20559         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
20560
20561         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20562
20563         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20564                 error "(2) Fail to copy"
20565
20566         trap cleanup_802a EXIT
20567
20568         # sync by force before remount as readonly
20569         sync; sync_all_data; sleep 3; sync_all_data
20570
20571         stopall
20572
20573         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
20574         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
20575         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
20576
20577         echo "Mount the server as read only"
20578         setupall server_only || error "(3) Fail to start servers"
20579
20580         echo "Mount client without ro should fail"
20581         mount_client $MOUNT &&
20582                 error "(4) Mount client without 'ro' should fail"
20583
20584         echo "Mount client with ro should succeed"
20585         mount_client $MOUNT ro ||
20586                 error "(5) Mount client with 'ro' should succeed"
20587
20588         echo "Modify should be refused"
20589         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20590
20591         echo "Read should be allowed"
20592         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20593                 error "(7) Read should succeed under ro mode"
20594
20595         cleanup_802a
20596 }
20597 run_test 802a "simulate readonly device"
20598
20599 test_802b() {
20600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20601         remote_mds_nodsh && skip "remote MDS with nodsh"
20602
20603         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
20604                 skip "readonly option not available"
20605
20606         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
20607
20608         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20609                 error "(2) Fail to copy"
20610
20611         # write back all cached data before setting MDT to readonly
20612         cancel_lru_locks
20613         sync_all_data
20614
20615         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
20616         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
20617
20618         echo "Modify should be refused"
20619         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20620
20621         echo "Read should be allowed"
20622         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20623                 error "(7) Read should succeed under ro mode"
20624
20625         # disable readonly
20626         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
20627 }
20628 run_test 802b "be able to set MDTs to readonly"
20629
20630 test_803() {
20631         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20632         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20633                 skip "MDS needs to be newer than 2.10.54"
20634
20635         mkdir -p $DIR/$tdir
20636         # Create some objects on all MDTs to trigger related logs objects
20637         for idx in $(seq $MDSCOUNT); do
20638                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
20639                         $DIR/$tdir/dir${idx} ||
20640                         error "Fail to create $DIR/$tdir/dir${idx}"
20641         done
20642
20643         sync; sleep 3
20644         wait_delete_completed # ensure old test cleanups are finished
20645         echo "before create:"
20646         $LFS df -i $MOUNT
20647         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20648
20649         for i in {1..10}; do
20650                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
20651                         error "Fail to create $DIR/$tdir/foo$i"
20652         done
20653
20654         sync; sleep 3
20655         echo "after create:"
20656         $LFS df -i $MOUNT
20657         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20658
20659         # allow for an llog to be cleaned up during the test
20660         [ $after_used -ge $((before_used + 10 - 1)) ] ||
20661                 error "before ($before_used) + 10 > after ($after_used)"
20662
20663         for i in {1..10}; do
20664                 rm -rf $DIR/$tdir/foo$i ||
20665                         error "Fail to remove $DIR/$tdir/foo$i"
20666         done
20667
20668         sleep 3 # avoid MDT return cached statfs
20669         wait_delete_completed
20670         echo "after unlink:"
20671         $LFS df -i $MOUNT
20672         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20673
20674         # allow for an llog to be created during the test
20675         [ $after_used -le $((before_used + 1)) ] ||
20676                 error "after ($after_used) > before ($before_used) + 1"
20677 }
20678 run_test 803 "verify agent object for remote object"
20679
20680 test_804() {
20681         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20682         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20683                 skip "MDS needs to be newer than 2.10.54"
20684         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20685
20686         mkdir -p $DIR/$tdir
20687         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20688                 error "Fail to create $DIR/$tdir/dir0"
20689
20690         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20691         local dev=$(mdsdevname 2)
20692
20693         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20694                 grep ${fid} || error "NOT found agent entry for dir0"
20695
20696         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20697                 error "Fail to create $DIR/$tdir/dir1"
20698
20699         touch $DIR/$tdir/dir1/foo0 ||
20700                 error "Fail to create $DIR/$tdir/dir1/foo0"
20701         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20702         local rc=0
20703
20704         for idx in $(seq $MDSCOUNT); do
20705                 dev=$(mdsdevname $idx)
20706                 do_facet mds${idx} \
20707                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20708                         grep ${fid} && rc=$idx
20709         done
20710
20711         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20712                 error "Fail to rename foo0 to foo1"
20713         if [ $rc -eq 0 ]; then
20714                 for idx in $(seq $MDSCOUNT); do
20715                         dev=$(mdsdevname $idx)
20716                         do_facet mds${idx} \
20717                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20718                         grep ${fid} && rc=$idx
20719                 done
20720         fi
20721
20722         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20723                 error "Fail to rename foo1 to foo2"
20724         if [ $rc -eq 0 ]; then
20725                 for idx in $(seq $MDSCOUNT); do
20726                         dev=$(mdsdevname $idx)
20727                         do_facet mds${idx} \
20728                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20729                         grep ${fid} && rc=$idx
20730                 done
20731         fi
20732
20733         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20734
20735         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20736                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20737         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20738                 error "Fail to rename foo2 to foo0"
20739         unlink $DIR/$tdir/dir1/foo0 ||
20740                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20741         rm -rf $DIR/$tdir/dir0 ||
20742                 error "Fail to rm $DIR/$tdir/dir0"
20743
20744         for idx in $(seq $MDSCOUNT); do
20745                 dev=$(mdsdevname $idx)
20746                 rc=0
20747
20748                 stop mds${idx}
20749                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20750                         rc=$?
20751                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20752                         error "mount mds$idx failed"
20753                 df $MOUNT > /dev/null 2>&1
20754
20755                 # e2fsck should not return error
20756                 [ $rc -eq 0 ] ||
20757                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20758         done
20759 }
20760 run_test 804 "verify agent entry for remote entry"
20761
20762 cleanup_805() {
20763         do_facet $SINGLEMDS zfs set quota=$old $fsset
20764         unlinkmany $DIR/$tdir/f- 1000000
20765         trap 0
20766 }
20767
20768 test_805() {
20769         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20770         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20771         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20772                 skip "netfree not implemented before 0.7"
20773         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20774                 skip "Need MDS version at least 2.10.57"
20775
20776         local fsset
20777         local freekb
20778         local usedkb
20779         local old
20780         local quota
20781         local pref="osd-zfs.lustre-MDT0000."
20782
20783         # limit available space on MDS dataset to meet nospace issue
20784         # quickly. then ZFS 0.7.2 can use reserved space if asked
20785         # properly (using netfree flag in osd_declare_destroy()
20786         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20787         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20788                 gawk '{print $3}')
20789         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20790         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20791         let "usedkb=usedkb-freekb"
20792         let "freekb=freekb/2"
20793         if let "freekb > 5000"; then
20794                 let "freekb=5000"
20795         fi
20796         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20797         trap cleanup_805 EXIT
20798         mkdir $DIR/$tdir
20799         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20800         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20801         rm -rf $DIR/$tdir || error "not able to remove"
20802         do_facet $SINGLEMDS zfs set quota=$old $fsset
20803         trap 0
20804 }
20805 run_test 805 "ZFS can remove from full fs"
20806
20807 # Size-on-MDS test
20808 check_lsom_data()
20809 {
20810         local file=$1
20811         local size=$($LFS getsom -s $file)
20812         local expect=$(stat -c %s $file)
20813
20814         [[ $size == $expect ]] ||
20815                 error "$file expected size: $expect, got: $size"
20816
20817         local blocks=$($LFS getsom -b $file)
20818         expect=$(stat -c %b $file)
20819         [[ $blocks == $expect ]] ||
20820                 error "$file expected blocks: $expect, got: $blocks"
20821 }
20822
20823 check_lsom_size()
20824 {
20825         local size=$($LFS getsom -s $1)
20826         local expect=$2
20827
20828         [[ $size == $expect ]] ||
20829                 error "$file expected size: $expect, got: $size"
20830 }
20831
20832 test_806() {
20833         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20834                 skip "Need MDS version at least 2.11.52"
20835
20836         local bs=1048576
20837
20838         touch $DIR/$tfile || error "touch $tfile failed"
20839
20840         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20841         save_lustre_params client "llite.*.xattr_cache" > $save
20842         lctl set_param llite.*.xattr_cache=0
20843         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20844
20845         # single-threaded write
20846         echo "Test SOM for single-threaded write"
20847         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20848                 error "write $tfile failed"
20849         check_lsom_size $DIR/$tfile $bs
20850
20851         local num=32
20852         local size=$(($num * $bs))
20853         local offset=0
20854         local i
20855
20856         echo "Test SOM for single client multi-threaded($num) write"
20857         $TRUNCATE $DIR/$tfile 0
20858         for ((i = 0; i < $num; i++)); do
20859                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20860                 local pids[$i]=$!
20861                 offset=$((offset + $bs))
20862         done
20863         for (( i=0; i < $num; i++ )); do
20864                 wait ${pids[$i]}
20865         done
20866         check_lsom_size $DIR/$tfile $size
20867
20868         $TRUNCATE $DIR/$tfile 0
20869         for ((i = 0; i < $num; i++)); do
20870                 offset=$((offset - $bs))
20871                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20872                 local pids[$i]=$!
20873         done
20874         for (( i=0; i < $num; i++ )); do
20875                 wait ${pids[$i]}
20876         done
20877         check_lsom_size $DIR/$tfile $size
20878
20879         # multi-client wirtes
20880         num=$(get_node_count ${CLIENTS//,/ })
20881         size=$(($num * $bs))
20882         offset=0
20883         i=0
20884
20885         echo "Test SOM for multi-client ($num) writes"
20886         $TRUNCATE $DIR/$tfile 0
20887         for client in ${CLIENTS//,/ }; do
20888                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20889                 local pids[$i]=$!
20890                 i=$((i + 1))
20891                 offset=$((offset + $bs))
20892         done
20893         for (( i=0; i < $num; i++ )); do
20894                 wait ${pids[$i]}
20895         done
20896         check_lsom_size $DIR/$tfile $offset
20897
20898         i=0
20899         $TRUNCATE $DIR/$tfile 0
20900         for client in ${CLIENTS//,/ }; do
20901                 offset=$((offset - $bs))
20902                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20903                 local pids[$i]=$!
20904                 i=$((i + 1))
20905         done
20906         for (( i=0; i < $num; i++ )); do
20907                 wait ${pids[$i]}
20908         done
20909         check_lsom_size $DIR/$tfile $size
20910
20911         # verify truncate
20912         echo "Test SOM for truncate"
20913         $TRUNCATE $DIR/$tfile 1048576
20914         check_lsom_size $DIR/$tfile 1048576
20915         $TRUNCATE $DIR/$tfile 1234
20916         check_lsom_size $DIR/$tfile 1234
20917
20918         # verify SOM blocks count
20919         echo "Verify SOM block count"
20920         $TRUNCATE $DIR/$tfile 0
20921         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20922                 error "failed to write file $tfile"
20923         check_lsom_data $DIR/$tfile
20924 }
20925 run_test 806 "Verify Lazy Size on MDS"
20926
20927 test_807() {
20928         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20929         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20930                 skip "Need MDS version at least 2.11.52"
20931
20932         # Registration step
20933         changelog_register || error "changelog_register failed"
20934         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20935         changelog_users $SINGLEMDS | grep -q $cl_user ||
20936                 error "User $cl_user not found in changelog_users"
20937
20938         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20939         save_lustre_params client "llite.*.xattr_cache" > $save
20940         lctl set_param llite.*.xattr_cache=0
20941         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20942
20943         rm -rf $DIR/$tdir || error "rm $tdir failed"
20944         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20945         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20946         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20947         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20948                 error "truncate $tdir/trunc failed"
20949
20950         local bs=1048576
20951         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20952                 error "write $tfile failed"
20953
20954         # multi-client wirtes
20955         local num=$(get_node_count ${CLIENTS//,/ })
20956         local offset=0
20957         local i=0
20958
20959         echo "Test SOM for multi-client ($num) writes"
20960         touch $DIR/$tfile || error "touch $tfile failed"
20961         $TRUNCATE $DIR/$tfile 0
20962         for client in ${CLIENTS//,/ }; do
20963                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20964                 local pids[$i]=$!
20965                 i=$((i + 1))
20966                 offset=$((offset + $bs))
20967         done
20968         for (( i=0; i < $num; i++ )); do
20969                 wait ${pids[$i]}
20970         done
20971
20972         sleep 5
20973         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20974         check_lsom_data $DIR/$tdir/trunc
20975         check_lsom_data $DIR/$tdir/single_dd
20976         check_lsom_data $DIR/$tfile
20977
20978         rm -rf $DIR/$tdir
20979         # Deregistration step
20980         changelog_deregister || error "changelog_deregister failed"
20981 }
20982 run_test 807 "verify LSOM syncing tool"
20983
20984 check_som_nologged()
20985 {
20986         local lines=$($LFS changelog $FSNAME-MDT0000 |
20987                 grep 'x=trusted.som' | wc -l)
20988         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
20989 }
20990
20991 test_808() {
20992         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
20993                 skip "Need MDS version at least 2.11.55"
20994
20995         # Registration step
20996         changelog_register || error "changelog_register failed"
20997
20998         touch $DIR/$tfile || error "touch $tfile failed"
20999         check_som_nologged
21000
21001         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
21002                 error "write $tfile failed"
21003         check_som_nologged
21004
21005         $TRUNCATE $DIR/$tfile 1234
21006         check_som_nologged
21007
21008         $TRUNCATE $DIR/$tfile 1048576
21009         check_som_nologged
21010
21011         # Deregistration step
21012         changelog_deregister || error "changelog_deregister failed"
21013 }
21014 run_test 808 "Check trusted.som xattr not logged in Changelogs"
21015
21016 check_som_nodata()
21017 {
21018         $LFS getsom $1
21019         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
21020 }
21021
21022 test_809() {
21023         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21024                 skip "Need MDS version at least 2.11.56"
21025
21026         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
21027                 error "failed to create DoM-only file $DIR/$tfile"
21028         touch $DIR/$tfile || error "touch $tfile failed"
21029         check_som_nodata $DIR/$tfile
21030
21031         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
21032                 error "write $tfile failed"
21033         check_som_nodata $DIR/$tfile
21034
21035         $TRUNCATE $DIR/$tfile 1234
21036         check_som_nodata $DIR/$tfile
21037
21038         $TRUNCATE $DIR/$tfile 4097
21039         check_som_nodata $DIR/$file
21040 }
21041 run_test 809 "Verify no SOM xattr store for DoM-only files"
21042
21043 test_810() {
21044         local ORIG
21045         local CSUM
21046
21047         # t10 seem to dislike partial pages
21048         lctl set_param osc.*.checksum_type=adler
21049         lctl set_param fail_loc=0x411
21050         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
21051         ORIG=$(md5sum $DIR/$tfile)
21052         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
21053         CSUM=$(md5sum $DIR/$tfile)
21054         set_checksum_type adler
21055         if [ "$ORIG" != "$CSUM" ]; then
21056                 error "$ORIG != $CSUM"
21057         fi
21058 }
21059 run_test 810 "partial page writes on ZFS (LU-11663)"
21060
21061 test_811() {
21062         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
21063                 skip "Need MDS version at least 2.11.56"
21064
21065         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
21066         do_facet mds1 $LCTL set_param fail_loc=0x165
21067         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
21068
21069         stop mds1
21070         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21071
21072         sleep 5
21073         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
21074                 error "MDD orphan cleanup thread not quit"
21075 }
21076 run_test 811 "orphan name stub can be cleaned up in startup"
21077
21078 test_812() {
21079         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
21080                 skip "OST < 2.12.51 doesn't support this fail_loc"
21081         [ "$SHARED_KEY" = true ] &&
21082                 skip "OSC connections never go IDLE with Shared-Keys enabled"
21083
21084         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21085         # ensure ost1 is connected
21086         stat $DIR/$tfile >/dev/null || error "can't stat"
21087         wait_osc_import_state client ost1 FULL
21088         # no locks, no reqs to let the connection idle
21089         cancel_lru_locks osc
21090
21091         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
21092 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
21093         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
21094         wait_osc_import_state client ost1 CONNECTING
21095         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
21096
21097         stat $DIR/$tfile >/dev/null || error "can't stat file"
21098 }
21099 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
21100
21101 test_813() {
21102         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
21103         [ -z "$file_heat_sav" ] && skip "no file heat support"
21104
21105         local readsample
21106         local writesample
21107         local readbyte
21108         local writebyte
21109         local readsample1
21110         local writesample1
21111         local readbyte1
21112         local writebyte1
21113
21114         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
21115         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
21116
21117         $LCTL set_param -n llite.*.file_heat=1
21118         echo "Turn on file heat"
21119         echo "Period second: $period_second, Decay percentage: $decay_pct"
21120
21121         echo "QQQQ" > $DIR/$tfile
21122         echo "QQQQ" > $DIR/$tfile
21123         echo "QQQQ" > $DIR/$tfile
21124         cat $DIR/$tfile > /dev/null
21125         cat $DIR/$tfile > /dev/null
21126         cat $DIR/$tfile > /dev/null
21127         cat $DIR/$tfile > /dev/null
21128
21129         local out=$($LFS heat_get $DIR/$tfile)
21130
21131         $LFS heat_get $DIR/$tfile
21132         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21133         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21134         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21135         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21136
21137         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
21138         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
21139         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
21140         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
21141
21142         sleep $((period_second + 3))
21143         echo "Sleep $((period_second + 3)) seconds..."
21144         # The recursion formula to calculate the heat of the file f is as
21145         # follow:
21146         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
21147         # Where Hi is the heat value in the period between time points i*I and
21148         # (i+1)*I; Ci is the access count in the period; the symbol P refers
21149         # to the weight of Ci.
21150         out=$($LFS heat_get $DIR/$tfile)
21151         $LFS heat_get $DIR/$tfile
21152         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21153         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21154         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21155         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21156
21157         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
21158                 error "read sample ($readsample) is wrong"
21159         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
21160                 error "write sample ($writesample) is wrong"
21161         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
21162                 error "read bytes ($readbyte) is wrong"
21163         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
21164                 error "write bytes ($writebyte) is wrong"
21165
21166         echo "QQQQ" > $DIR/$tfile
21167         echo "QQQQ" > $DIR/$tfile
21168         echo "QQQQ" > $DIR/$tfile
21169         cat $DIR/$tfile > /dev/null
21170         cat $DIR/$tfile > /dev/null
21171         cat $DIR/$tfile > /dev/null
21172         cat $DIR/$tfile > /dev/null
21173
21174         sleep $((period_second + 3))
21175         echo "Sleep $((period_second + 3)) seconds..."
21176
21177         out=$($LFS heat_get $DIR/$tfile)
21178         $LFS heat_get $DIR/$tfile
21179         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21180         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21181         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21182         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21183
21184         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
21185                 4 * $decay_pct) / 100") -eq 1 ] ||
21186                 error "read sample ($readsample1) is wrong"
21187         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
21188                 3 * $decay_pct) / 100") -eq 1 ] ||
21189                 error "write sample ($writesample1) is wrong"
21190         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
21191                 20 * $decay_pct) / 100") -eq 1 ] ||
21192                 error "read bytes ($readbyte1) is wrong"
21193         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
21194                 15 * $decay_pct) / 100") -eq 1 ] ||
21195                 error "write bytes ($writebyte1) is wrong"
21196
21197         echo "Turn off file heat for the file $DIR/$tfile"
21198         $LFS heat_set -o $DIR/$tfile
21199
21200         echo "QQQQ" > $DIR/$tfile
21201         echo "QQQQ" > $DIR/$tfile
21202         echo "QQQQ" > $DIR/$tfile
21203         cat $DIR/$tfile > /dev/null
21204         cat $DIR/$tfile > /dev/null
21205         cat $DIR/$tfile > /dev/null
21206         cat $DIR/$tfile > /dev/null
21207
21208         out=$($LFS heat_get $DIR/$tfile)
21209         $LFS heat_get $DIR/$tfile
21210         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21211         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21212         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21213         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21214
21215         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21216         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21217         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21218         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21219
21220         echo "Trun on file heat for the file $DIR/$tfile"
21221         $LFS heat_set -O $DIR/$tfile
21222
21223         echo "QQQQ" > $DIR/$tfile
21224         echo "QQQQ" > $DIR/$tfile
21225         echo "QQQQ" > $DIR/$tfile
21226         cat $DIR/$tfile > /dev/null
21227         cat $DIR/$tfile > /dev/null
21228         cat $DIR/$tfile > /dev/null
21229         cat $DIR/$tfile > /dev/null
21230
21231         out=$($LFS heat_get $DIR/$tfile)
21232         $LFS heat_get $DIR/$tfile
21233         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21234         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21235         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21236         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21237
21238         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
21239         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
21240         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
21241         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
21242
21243         $LFS heat_set -c $DIR/$tfile
21244         $LCTL set_param -n llite.*.file_heat=0
21245         echo "Turn off file heat support for the Lustre filesystem"
21246
21247         echo "QQQQ" > $DIR/$tfile
21248         echo "QQQQ" > $DIR/$tfile
21249         echo "QQQQ" > $DIR/$tfile
21250         cat $DIR/$tfile > /dev/null
21251         cat $DIR/$tfile > /dev/null
21252         cat $DIR/$tfile > /dev/null
21253         cat $DIR/$tfile > /dev/null
21254
21255         out=$($LFS heat_get $DIR/$tfile)
21256         $LFS heat_get $DIR/$tfile
21257         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21258         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21259         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21260         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21261
21262         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21263         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21264         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21265         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21266
21267         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
21268         rm -f $DIR/$tfile
21269 }
21270 run_test 813 "File heat verfication"
21271
21272 test_814()
21273 {
21274         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
21275         echo -n y >> $DIR/$tfile
21276         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
21277         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
21278 }
21279 run_test 814 "sparse cp works as expected (LU-12361)"
21280
21281 test_815()
21282 {
21283         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
21284         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
21285 }
21286 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
21287
21288 test_816() {
21289         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21290         # ensure ost1 is connected
21291         stat $DIR/$tfile >/dev/null || error "can't stat"
21292         wait_osc_import_state client ost1 FULL
21293         # no locks, no reqs to let the connection idle
21294         cancel_lru_locks osc
21295         lru_resize_disable osc
21296         local before
21297         local now
21298         before=$($LCTL get_param -n \
21299                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
21300
21301         wait_osc_import_state client ost1 IDLE
21302         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
21303         now=$($LCTL get_param -n \
21304               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
21305         [ $before == $now ] || error "lru_size changed $before != $now"
21306 }
21307 run_test 816 "do not reset lru_resize on idle reconnect"
21308
21309 #
21310 # tests that do cleanup/setup should be run at the end
21311 #
21312
21313 test_900() {
21314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21315         local ls
21316
21317         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
21318         $LCTL set_param fail_loc=0x903
21319
21320         cancel_lru_locks MGC
21321
21322         FAIL_ON_ERROR=true cleanup
21323         FAIL_ON_ERROR=true setup
21324 }
21325 run_test 900 "umount should not race with any mgc requeue thread"
21326
21327 complete $SECONDS
21328 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
21329 check_and_cleanup_lustre
21330 if [ "$I_MOUNTED" != "yes" ]; then
21331         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
21332 fi
21333 exit_status