Whamcloud - gitweb
59f1210f7f61a1982df5eb8326deec052e00182a
[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 LU-4398
57         ALWAYS_EXCEPT+=" 45       103a      317      810       817"
58 fi
59
60 #                                  5          12          (min)"
61 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
62
63 if [ "$mds1_FSTYPE" = "zfs" ]; then
64         # bug number for skipped test: 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 test_27L() {
2814         remote_mds_nodsh && skip "remote MDS with nodsh"
2815
2816         local POOL=${POOL:-$TESTNAME}
2817
2818         if ! combined_mgs_mds ; then
2819                 mount_mgs_client
2820                 trap umount_mgs_client EXIT
2821         fi
2822
2823         pool_add $POOL || error "pool_add failed"
2824
2825         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2826                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2827                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2828 }
2829 run_test 27L "lfs pool_list gives correct pool name"
2830
2831 # createtest also checks that device nodes are created and
2832 # then visible correctly (#2091)
2833 test_28() { # bug 2091
2834         test_mkdir $DIR/d28
2835         $CREATETEST $DIR/d28/ct || error "createtest failed"
2836 }
2837 run_test 28 "create/mknod/mkdir with bad file types ============"
2838
2839 test_29() {
2840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2841
2842         sync; sleep 1; sync # flush out any dirty pages from previous tests
2843         cancel_lru_locks
2844         test_mkdir $DIR/d29
2845         touch $DIR/d29/foo
2846         log 'first d29'
2847         ls -l $DIR/d29
2848
2849         declare -i LOCKCOUNTORIG=0
2850         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2851                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2852         done
2853         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2854
2855         declare -i LOCKUNUSEDCOUNTORIG=0
2856         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2857                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2858         done
2859
2860         log 'second d29'
2861         ls -l $DIR/d29
2862         log 'done'
2863
2864         declare -i LOCKCOUNTCURRENT=0
2865         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2866                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2867         done
2868
2869         declare -i LOCKUNUSEDCOUNTCURRENT=0
2870         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2871                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2872         done
2873
2874         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2875                 $LCTL set_param -n ldlm.dump_namespaces ""
2876                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2877                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2878                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2879                 return 2
2880         fi
2881         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2882                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2883                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2884                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2885                 return 3
2886         fi
2887 }
2888 run_test 29 "IT_GETATTR regression  ============================"
2889
2890 test_30a() { # was test_30
2891         cp $(which ls) $DIR || cp /bin/ls $DIR
2892         $DIR/ls / || error "Can't execute binary from lustre"
2893         rm $DIR/ls
2894 }
2895 run_test 30a "execute binary from Lustre (execve) =============="
2896
2897 test_30b() {
2898         cp `which ls` $DIR || cp /bin/ls $DIR
2899         chmod go+rx $DIR/ls
2900         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2901         rm $DIR/ls
2902 }
2903 run_test 30b "execute binary from Lustre as non-root ==========="
2904
2905 test_30c() { # b=22376
2906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2907
2908         cp `which ls` $DIR || cp /bin/ls $DIR
2909         chmod a-rw $DIR/ls
2910         cancel_lru_locks mdc
2911         cancel_lru_locks osc
2912         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2913         rm -f $DIR/ls
2914 }
2915 run_test 30c "execute binary from Lustre without read perms ===="
2916
2917 test_31a() {
2918         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2919         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2920 }
2921 run_test 31a "open-unlink file =================================="
2922
2923 test_31b() {
2924         touch $DIR/f31 || error "touch $DIR/f31 failed"
2925         ln $DIR/f31 $DIR/f31b || error "ln failed"
2926         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2927         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2928 }
2929 run_test 31b "unlink file with multiple links while open ======="
2930
2931 test_31c() {
2932         touch $DIR/f31 || error "touch $DIR/f31 failed"
2933         ln $DIR/f31 $DIR/f31c || error "ln failed"
2934         multiop_bg_pause $DIR/f31 O_uc ||
2935                 error "multiop_bg_pause for $DIR/f31 failed"
2936         MULTIPID=$!
2937         $MULTIOP $DIR/f31c Ouc
2938         kill -USR1 $MULTIPID
2939         wait $MULTIPID
2940 }
2941 run_test 31c "open-unlink file with multiple links ============="
2942
2943 test_31d() {
2944         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2945         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2946 }
2947 run_test 31d "remove of open directory ========================="
2948
2949 test_31e() { # bug 2904
2950         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2951 }
2952 run_test 31e "remove of open non-empty directory ==============="
2953
2954 test_31f() { # bug 4554
2955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2956
2957         set -vx
2958         test_mkdir $DIR/d31f
2959         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2960         cp /etc/hosts $DIR/d31f
2961         ls -l $DIR/d31f
2962         $LFS getstripe $DIR/d31f/hosts
2963         multiop_bg_pause $DIR/d31f D_c || return 1
2964         MULTIPID=$!
2965
2966         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2967         test_mkdir $DIR/d31f
2968         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2969         cp /etc/hosts $DIR/d31f
2970         ls -l $DIR/d31f
2971         $LFS getstripe $DIR/d31f/hosts
2972         multiop_bg_pause $DIR/d31f D_c || return 1
2973         MULTIPID2=$!
2974
2975         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2976         wait $MULTIPID || error "first opendir $MULTIPID failed"
2977
2978         sleep 6
2979
2980         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2981         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2982         set +vx
2983 }
2984 run_test 31f "remove of open directory with open-unlink file ==="
2985
2986 test_31g() {
2987         echo "-- cross directory link --"
2988         test_mkdir -c1 $DIR/${tdir}ga
2989         test_mkdir -c1 $DIR/${tdir}gb
2990         touch $DIR/${tdir}ga/f
2991         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2992         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2993         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2994         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2995         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2996 }
2997 run_test 31g "cross directory link==============="
2998
2999 test_31h() {
3000         echo "-- cross directory link --"
3001         test_mkdir -c1 $DIR/${tdir}
3002         test_mkdir -c1 $DIR/${tdir}/dir
3003         touch $DIR/${tdir}/f
3004         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3005         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3006         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3007         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3008         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3009 }
3010 run_test 31h "cross directory link under child==============="
3011
3012 test_31i() {
3013         echo "-- cross directory link --"
3014         test_mkdir -c1 $DIR/$tdir
3015         test_mkdir -c1 $DIR/$tdir/dir
3016         touch $DIR/$tdir/dir/f
3017         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3018         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3019         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3020         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3021         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3022 }
3023 run_test 31i "cross directory link under parent==============="
3024
3025 test_31j() {
3026         test_mkdir -c1 -p $DIR/$tdir
3027         test_mkdir -c1 -p $DIR/$tdir/dir1
3028         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3029         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3030         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3031         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3032         return 0
3033 }
3034 run_test 31j "link for directory==============="
3035
3036 test_31k() {
3037         test_mkdir -c1 -p $DIR/$tdir
3038         touch $DIR/$tdir/s
3039         touch $DIR/$tdir/exist
3040         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3041         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3042         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3043         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3044         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3045         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3046         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3047         return 0
3048 }
3049 run_test 31k "link to file: the same, non-existing, dir==============="
3050
3051 test_31m() {
3052         mkdir $DIR/d31m
3053         touch $DIR/d31m/s
3054         mkdir $DIR/d31m2
3055         touch $DIR/d31m2/exist
3056         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3057         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3058         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3059         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3060         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3061         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3062         return 0
3063 }
3064 run_test 31m "link to file: the same, non-existing, dir==============="
3065
3066 test_31n() {
3067         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3068         nlink=$(stat --format=%h $DIR/$tfile)
3069         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3070         local fd=$(free_fd)
3071         local cmd="exec $fd<$DIR/$tfile"
3072         eval $cmd
3073         cmd="exec $fd<&-"
3074         trap "eval $cmd" EXIT
3075         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3076         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3077         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3078         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3079         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3080         eval $cmd
3081 }
3082 run_test 31n "check link count of unlinked file"
3083
3084 link_one() {
3085         local TEMPNAME=$(mktemp $1_XXXXXX)
3086         mlink $TEMPNAME $1 2> /dev/null &&
3087                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
3088         munlink $TEMPNAME
3089 }
3090
3091 test_31o() { # LU-2901
3092         test_mkdir $DIR/$tdir
3093         for LOOP in $(seq 100); do
3094                 rm -f $DIR/$tdir/$tfile*
3095                 for THREAD in $(seq 8); do
3096                         link_one $DIR/$tdir/$tfile.$LOOP &
3097                 done
3098                 wait
3099                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3100                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3101                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3102                         break || true
3103         done
3104 }
3105 run_test 31o "duplicate hard links with same filename"
3106
3107 test_31p() {
3108         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3109
3110         test_mkdir $DIR/$tdir
3111         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3112         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3113
3114         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3115                 error "open unlink test1 failed"
3116         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3117                 error "open unlink test2 failed"
3118
3119         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3120                 error "test1 still exists"
3121         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3122                 error "test2 still exists"
3123 }
3124 run_test 31p "remove of open striped directory"
3125
3126 cleanup_test32_mount() {
3127         local rc=0
3128         trap 0
3129         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3130         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3131         losetup -d $loopdev || true
3132         rm -rf $DIR/$tdir
3133         return $rc
3134 }
3135
3136 test_32a() {
3137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3138
3139         echo "== more mountpoints and symlinks ================="
3140         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3141         trap cleanup_test32_mount EXIT
3142         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3143         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3144                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3145         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3146                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3147         cleanup_test32_mount
3148 }
3149 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3150
3151 test_32b() {
3152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3153
3154         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3155         trap cleanup_test32_mount EXIT
3156         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3157         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3158                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3159         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3160                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3161         cleanup_test32_mount
3162 }
3163 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3164
3165 test_32c() {
3166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3167
3168         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3169         trap cleanup_test32_mount EXIT
3170         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3171         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3172                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3173         test_mkdir -p $DIR/$tdir/d2/test_dir
3174         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3175                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3176         cleanup_test32_mount
3177 }
3178 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3179
3180 test_32d() {
3181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3182
3183         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3184         trap cleanup_test32_mount EXIT
3185         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3186         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3187                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3188         test_mkdir -p $DIR/$tdir/d2/test_dir
3189         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3190                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3191         cleanup_test32_mount
3192 }
3193 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3194
3195 test_32e() {
3196         rm -fr $DIR/$tdir
3197         test_mkdir -p $DIR/$tdir/tmp
3198         local tmp_dir=$DIR/$tdir/tmp
3199         ln -s $DIR/$tdir $tmp_dir/symlink11
3200         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3201         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3202         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3203 }
3204 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3205
3206 test_32f() {
3207         rm -fr $DIR/$tdir
3208         test_mkdir -p $DIR/$tdir/tmp
3209         local tmp_dir=$DIR/$tdir/tmp
3210         ln -s $DIR/$tdir $tmp_dir/symlink11
3211         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3212         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3213         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3214 }
3215 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3216
3217 test_32g() {
3218         local tmp_dir=$DIR/$tdir/tmp
3219         test_mkdir -p $tmp_dir
3220         test_mkdir $DIR/${tdir}2
3221         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3222         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3223         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3224         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3225         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3226         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3227 }
3228 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3229
3230 test_32h() {
3231         rm -fr $DIR/$tdir $DIR/${tdir}2
3232         tmp_dir=$DIR/$tdir/tmp
3233         test_mkdir -p $tmp_dir
3234         test_mkdir $DIR/${tdir}2
3235         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3236         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3237         ls $tmp_dir/symlink12 || error "listing symlink12"
3238         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3239 }
3240 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3241
3242 test_32i() {
3243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3244
3245         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3246         trap cleanup_test32_mount EXIT
3247         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3248         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3249                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3250         touch $DIR/$tdir/test_file
3251         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3252                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3253         cleanup_test32_mount
3254 }
3255 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3256
3257 test_32j() {
3258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3259
3260         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3261         trap cleanup_test32_mount EXIT
3262         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3263         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3264                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3265         touch $DIR/$tdir/test_file
3266         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3267                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3268         cleanup_test32_mount
3269 }
3270 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3271
3272 test_32k() {
3273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3274
3275         rm -fr $DIR/$tdir
3276         trap cleanup_test32_mount EXIT
3277         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3278         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3279                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3280         test_mkdir -p $DIR/$tdir/d2
3281         touch $DIR/$tdir/d2/test_file || error "touch failed"
3282         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3283                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3284         cleanup_test32_mount
3285 }
3286 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3287
3288 test_32l() {
3289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3290
3291         rm -fr $DIR/$tdir
3292         trap cleanup_test32_mount EXIT
3293         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3294         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3295                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3296         test_mkdir -p $DIR/$tdir/d2
3297         touch $DIR/$tdir/d2/test_file || error "touch failed"
3298         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3299                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3300         cleanup_test32_mount
3301 }
3302 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3303
3304 test_32m() {
3305         rm -fr $DIR/d32m
3306         test_mkdir -p $DIR/d32m/tmp
3307         TMP_DIR=$DIR/d32m/tmp
3308         ln -s $DIR $TMP_DIR/symlink11
3309         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3310         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3311                 error "symlink11 not a link"
3312         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3313                 error "symlink01 not a link"
3314 }
3315 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3316
3317 test_32n() {
3318         rm -fr $DIR/d32n
3319         test_mkdir -p $DIR/d32n/tmp
3320         TMP_DIR=$DIR/d32n/tmp
3321         ln -s $DIR $TMP_DIR/symlink11
3322         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3323         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3324         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3325 }
3326 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3327
3328 test_32o() {
3329         touch $DIR/$tfile
3330         test_mkdir -p $DIR/d32o/tmp
3331         TMP_DIR=$DIR/d32o/tmp
3332         ln -s $DIR/$tfile $TMP_DIR/symlink12
3333         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3334         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3335                 error "symlink12 not a link"
3336         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3337         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3338                 error "$DIR/d32o/tmp/symlink12 not file type"
3339         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3340                 error "$DIR/d32o/symlink02 not file type"
3341 }
3342 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3343
3344 test_32p() {
3345         log 32p_1
3346         rm -fr $DIR/d32p
3347         log 32p_2
3348         rm -f $DIR/$tfile
3349         log 32p_3
3350         touch $DIR/$tfile
3351         log 32p_4
3352         test_mkdir -p $DIR/d32p/tmp
3353         log 32p_5
3354         TMP_DIR=$DIR/d32p/tmp
3355         log 32p_6
3356         ln -s $DIR/$tfile $TMP_DIR/symlink12
3357         log 32p_7
3358         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3359         log 32p_8
3360         cat $DIR/d32p/tmp/symlink12 ||
3361                 error "Can't open $DIR/d32p/tmp/symlink12"
3362         log 32p_9
3363         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3364         log 32p_10
3365 }
3366 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3367
3368 test_32q() {
3369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3370
3371         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3372         trap cleanup_test32_mount EXIT
3373         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3374         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3375         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3376                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3377         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3378         cleanup_test32_mount
3379 }
3380 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3381
3382 test_32r() {
3383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3384
3385         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3386         trap cleanup_test32_mount EXIT
3387         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3388         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3389         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3390                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3391         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3392         cleanup_test32_mount
3393 }
3394 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3395
3396 test_33aa() {
3397         rm -f $DIR/$tfile
3398         touch $DIR/$tfile
3399         chmod 444 $DIR/$tfile
3400         chown $RUNAS_ID $DIR/$tfile
3401         log 33_1
3402         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3403         log 33_2
3404 }
3405 run_test 33aa "write file with mode 444 (should return error)"
3406
3407 test_33a() {
3408         rm -fr $DIR/$tdir
3409         test_mkdir $DIR/$tdir
3410         chown $RUNAS_ID $DIR/$tdir
3411         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3412                 error "$RUNAS create $tdir/$tfile failed"
3413         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3414                 error "open RDWR" || true
3415 }
3416 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3417
3418 test_33b() {
3419         rm -fr $DIR/$tdir
3420         test_mkdir $DIR/$tdir
3421         chown $RUNAS_ID $DIR/$tdir
3422         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3423 }
3424 run_test 33b "test open file with malformed flags (No panic)"
3425
3426 test_33c() {
3427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3428         remote_ost_nodsh && skip "remote OST with nodsh"
3429
3430         local ostnum
3431         local ostname
3432         local write_bytes
3433         local all_zeros
3434
3435         all_zeros=:
3436         rm -fr $DIR/$tdir
3437         test_mkdir $DIR/$tdir
3438         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3439
3440         sync
3441         for ostnum in $(seq $OSTCOUNT); do
3442                 # test-framework's OST numbering is one-based, while Lustre's
3443                 # is zero-based
3444                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3445                 # Parsing llobdstat's output sucks; we could grep the /proc
3446                 # path, but that's likely to not be as portable as using the
3447                 # llobdstat utility.  So we parse lctl output instead.
3448                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3449                         obdfilter/$ostname/stats |
3450                         awk '/^write_bytes/ {print $7}' )
3451                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3452                 if (( ${write_bytes:-0} > 0 ))
3453                 then
3454                         all_zeros=false
3455                         break;
3456                 fi
3457         done
3458
3459         $all_zeros || return 0
3460
3461         # Write four bytes
3462         echo foo > $DIR/$tdir/bar
3463         # Really write them
3464         sync
3465
3466         # Total up write_bytes after writing.  We'd better find non-zeros.
3467         for ostnum in $(seq $OSTCOUNT); do
3468                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3469                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3470                         obdfilter/$ostname/stats |
3471                         awk '/^write_bytes/ {print $7}' )
3472                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3473                 if (( ${write_bytes:-0} > 0 ))
3474                 then
3475                         all_zeros=false
3476                         break;
3477                 fi
3478         done
3479
3480         if $all_zeros
3481         then
3482                 for ostnum in $(seq $OSTCOUNT); do
3483                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3484                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3485                         do_facet ost$ostnum lctl get_param -n \
3486                                 obdfilter/$ostname/stats
3487                 done
3488                 error "OST not keeping write_bytes stats (b22312)"
3489         fi
3490 }
3491 run_test 33c "test llobdstat and write_bytes"
3492
3493 test_33d() {
3494         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3496
3497         local MDTIDX=1
3498         local remote_dir=$DIR/$tdir/remote_dir
3499
3500         test_mkdir $DIR/$tdir
3501         $LFS mkdir -i $MDTIDX $remote_dir ||
3502                 error "create remote directory failed"
3503
3504         touch $remote_dir/$tfile
3505         chmod 444 $remote_dir/$tfile
3506         chown $RUNAS_ID $remote_dir/$tfile
3507
3508         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3509
3510         chown $RUNAS_ID $remote_dir
3511         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3512                                         error "create" || true
3513         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3514                                     error "open RDWR" || true
3515         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3516 }
3517 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3518
3519 test_33e() {
3520         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3521
3522         mkdir $DIR/$tdir
3523
3524         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3525         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3526         mkdir $DIR/$tdir/local_dir
3527
3528         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3529         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3530         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3531
3532         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3533                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3534
3535         rmdir $DIR/$tdir/* || error "rmdir failed"
3536
3537         umask 777
3538         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3539         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3540         mkdir $DIR/$tdir/local_dir
3541
3542         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3543         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3544         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3545
3546         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3547                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3548
3549         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3550
3551         umask 000
3552         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3553         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3554         mkdir $DIR/$tdir/local_dir
3555
3556         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3557         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3558         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3559
3560         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3561                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3562 }
3563 run_test 33e "mkdir and striped directory should have same mode"
3564
3565 cleanup_33f() {
3566         trap 0
3567         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3568 }
3569
3570 test_33f() {
3571         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3572         remote_mds_nodsh && skip "remote MDS with nodsh"
3573
3574         mkdir $DIR/$tdir
3575         chmod go+rwx $DIR/$tdir
3576         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3577         trap cleanup_33f EXIT
3578
3579         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3580                 error "cannot create striped directory"
3581
3582         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3583                 error "cannot create files in striped directory"
3584
3585         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3586                 error "cannot remove files in striped directory"
3587
3588         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3589                 error "cannot remove striped directory"
3590
3591         cleanup_33f
3592 }
3593 run_test 33f "nonroot user can create, access, and remove a striped directory"
3594
3595 test_33g() {
3596         mkdir -p $DIR/$tdir/dir2
3597
3598         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3599         echo $err
3600         [[ $err =~ "exists" ]] || error "Not exists error"
3601 }
3602 run_test 33g "nonroot user create already existing root created file"
3603
3604 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3605 test_34a() {
3606         rm -f $DIR/f34
3607         $MCREATE $DIR/f34 || error "mcreate failed"
3608         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3609                 error "getstripe failed"
3610         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3611         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3612                 error "getstripe failed"
3613         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3614                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3615 }
3616 run_test 34a "truncate file that has not been opened ==========="
3617
3618 test_34b() {
3619         [ ! -f $DIR/f34 ] && test_34a
3620         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3621                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3622         $OPENFILE -f O_RDONLY $DIR/f34
3623         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3624                 error "getstripe failed"
3625         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3626                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3627 }
3628 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3629
3630 test_34c() {
3631         [ ! -f $DIR/f34 ] && test_34a
3632         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3633                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3634         $OPENFILE -f O_RDWR $DIR/f34
3635         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3636                 error "$LFS getstripe failed"
3637         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3638                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3639 }
3640 run_test 34c "O_RDWR opening file-with-size works =============="
3641
3642 test_34d() {
3643         [ ! -f $DIR/f34 ] && test_34a
3644         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3645                 error "dd failed"
3646         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3647                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3648         rm $DIR/f34
3649 }
3650 run_test 34d "write to sparse file ============================="
3651
3652 test_34e() {
3653         rm -f $DIR/f34e
3654         $MCREATE $DIR/f34e || error "mcreate failed"
3655         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3656         $CHECKSTAT -s 1000 $DIR/f34e ||
3657                 error "Size of $DIR/f34e not equal to 1000 bytes"
3658         $OPENFILE -f O_RDWR $DIR/f34e
3659         $CHECKSTAT -s 1000 $DIR/f34e ||
3660                 error "Size of $DIR/f34e not equal to 1000 bytes"
3661 }
3662 run_test 34e "create objects, some with size and some without =="
3663
3664 test_34f() { # bug 6242, 6243
3665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3666
3667         SIZE34F=48000
3668         rm -f $DIR/f34f
3669         $MCREATE $DIR/f34f || error "mcreate failed"
3670         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3671         dd if=$DIR/f34f of=$TMP/f34f
3672         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3673         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3674         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3675         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3676         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3677 }
3678 run_test 34f "read from a file with no objects until EOF ======="
3679
3680 test_34g() {
3681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3682
3683         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3684                 error "dd failed"
3685         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3686         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3687                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3688         cancel_lru_locks osc
3689         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3690                 error "wrong size after lock cancel"
3691
3692         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3693         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3694                 error "expanding truncate failed"
3695         cancel_lru_locks osc
3696         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3697                 error "wrong expanded size after lock cancel"
3698 }
3699 run_test 34g "truncate long file ==============================="
3700
3701 test_34h() {
3702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3703
3704         local gid=10
3705         local sz=1000
3706
3707         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3708         sync # Flush the cache so that multiop below does not block on cache
3709              # flush when getting the group lock
3710         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3711         MULTIPID=$!
3712
3713         # Since just timed wait is not good enough, let's do a sync write
3714         # that way we are sure enough time for a roundtrip + processing
3715         # passed + 2 seconds of extra margin.
3716         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3717         rm $DIR/${tfile}-1
3718         sleep 2
3719
3720         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3721                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3722                 kill -9 $MULTIPID
3723         fi
3724         wait $MULTIPID
3725         local nsz=`stat -c %s $DIR/$tfile`
3726         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3727 }
3728 run_test 34h "ftruncate file under grouplock should not block"
3729
3730 test_35a() {
3731         cp /bin/sh $DIR/f35a
3732         chmod 444 $DIR/f35a
3733         chown $RUNAS_ID $DIR/f35a
3734         $RUNAS $DIR/f35a && error || true
3735         rm $DIR/f35a
3736 }
3737 run_test 35a "exec file with mode 444 (should return and not leak)"
3738
3739 test_36a() {
3740         rm -f $DIR/f36
3741         utime $DIR/f36 || error "utime failed for MDS"
3742 }
3743 run_test 36a "MDS utime check (mknod, utime)"
3744
3745 test_36b() {
3746         echo "" > $DIR/f36
3747         utime $DIR/f36 || error "utime failed for OST"
3748 }
3749 run_test 36b "OST utime check (open, utime)"
3750
3751 test_36c() {
3752         rm -f $DIR/d36/f36
3753         test_mkdir $DIR/d36
3754         chown $RUNAS_ID $DIR/d36
3755         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3756 }
3757 run_test 36c "non-root MDS utime check (mknod, utime)"
3758
3759 test_36d() {
3760         [ ! -d $DIR/d36 ] && test_36c
3761         echo "" > $DIR/d36/f36
3762         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3763 }
3764 run_test 36d "non-root OST utime check (open, utime)"
3765
3766 test_36e() {
3767         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3768
3769         test_mkdir $DIR/$tdir
3770         touch $DIR/$tdir/$tfile
3771         $RUNAS utime $DIR/$tdir/$tfile &&
3772                 error "utime worked, expected failure" || true
3773 }
3774 run_test 36e "utime on non-owned file (should return error)"
3775
3776 subr_36fh() {
3777         local fl="$1"
3778         local LANG_SAVE=$LANG
3779         local LC_LANG_SAVE=$LC_LANG
3780         export LANG=C LC_LANG=C # for date language
3781
3782         DATESTR="Dec 20  2000"
3783         test_mkdir $DIR/$tdir
3784         lctl set_param fail_loc=$fl
3785         date; date +%s
3786         cp /etc/hosts $DIR/$tdir/$tfile
3787         sync & # write RPC generated with "current" inode timestamp, but delayed
3788         sleep 1
3789         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3790         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3791         cancel_lru_locks $OSC
3792         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3793         date; date +%s
3794         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3795                 echo "BEFORE: $LS_BEFORE" && \
3796                 echo "AFTER : $LS_AFTER" && \
3797                 echo "WANT  : $DATESTR" && \
3798                 error "$DIR/$tdir/$tfile timestamps changed" || true
3799
3800         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3801 }
3802
3803 test_36f() {
3804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3805
3806         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3807         subr_36fh "0x80000214"
3808 }
3809 run_test 36f "utime on file racing with OST BRW write =========="
3810
3811 test_36g() {
3812         remote_ost_nodsh && skip "remote OST with nodsh"
3813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3814         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3815                 skip "Need MDS version at least 2.12.51"
3816
3817         local fmd_max_age
3818         local fmd
3819         local facet="ost1"
3820         local tgt="obdfilter"
3821
3822         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3823
3824         test_mkdir $DIR/$tdir
3825         fmd_max_age=$(do_facet $facet \
3826                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3827                 head -n 1")
3828
3829         echo "FMD max age: ${fmd_max_age}s"
3830         touch $DIR/$tdir/$tfile
3831         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3832                 gawk '{cnt=cnt+$1}  END{print cnt}')
3833         echo "FMD before: $fmd"
3834         [[ $fmd == 0 ]] &&
3835                 error "FMD wasn't create by touch"
3836         sleep $((fmd_max_age + 12))
3837         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3838                 gawk '{cnt=cnt+$1}  END{print cnt}')
3839         echo "FMD after: $fmd"
3840         [[ $fmd == 0 ]] ||
3841                 error "FMD wasn't expired by ping"
3842 }
3843 run_test 36g "FMD cache expiry ====================="
3844
3845 test_36h() {
3846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3847
3848         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3849         subr_36fh "0x80000227"
3850 }
3851 run_test 36h "utime on file racing with OST BRW write =========="
3852
3853 test_36i() {
3854         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3855
3856         test_mkdir $DIR/$tdir
3857         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3858
3859         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3860         local new_mtime=$((mtime + 200))
3861
3862         #change Modify time of striped dir
3863         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3864                         error "change mtime failed"
3865
3866         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3867
3868         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3869 }
3870 run_test 36i "change mtime on striped directory"
3871
3872 # test_37 - duplicate with tests 32q 32r
3873
3874 test_38() {
3875         local file=$DIR/$tfile
3876         touch $file
3877         openfile -f O_DIRECTORY $file
3878         local RC=$?
3879         local ENOTDIR=20
3880         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3881         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3882 }
3883 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3884
3885 test_39a() { # was test_39
3886         touch $DIR/$tfile
3887         touch $DIR/${tfile}2
3888 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3889 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3890 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3891         sleep 2
3892         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3893         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3894                 echo "mtime"
3895                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3896                 echo "atime"
3897                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3898                 echo "ctime"
3899                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3900                 error "O_TRUNC didn't change timestamps"
3901         fi
3902 }
3903 run_test 39a "mtime changed on create"
3904
3905 test_39b() {
3906         test_mkdir -c1 $DIR/$tdir
3907         cp -p /etc/passwd $DIR/$tdir/fopen
3908         cp -p /etc/passwd $DIR/$tdir/flink
3909         cp -p /etc/passwd $DIR/$tdir/funlink
3910         cp -p /etc/passwd $DIR/$tdir/frename
3911         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3912
3913         sleep 1
3914         echo "aaaaaa" >> $DIR/$tdir/fopen
3915         echo "aaaaaa" >> $DIR/$tdir/flink
3916         echo "aaaaaa" >> $DIR/$tdir/funlink
3917         echo "aaaaaa" >> $DIR/$tdir/frename
3918
3919         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3920         local link_new=`stat -c %Y $DIR/$tdir/flink`
3921         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3922         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3923
3924         cat $DIR/$tdir/fopen > /dev/null
3925         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3926         rm -f $DIR/$tdir/funlink2
3927         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3928
3929         for (( i=0; i < 2; i++ )) ; do
3930                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3931                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3932                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3933                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3934
3935                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3936                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3937                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3938                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3939
3940                 cancel_lru_locks $OSC
3941                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3942         done
3943 }
3944 run_test 39b "mtime change on open, link, unlink, rename  ======"
3945
3946 # this should be set to past
3947 TEST_39_MTIME=`date -d "1 year ago" +%s`
3948
3949 # bug 11063
3950 test_39c() {
3951         touch $DIR1/$tfile
3952         sleep 2
3953         local mtime0=`stat -c %Y $DIR1/$tfile`
3954
3955         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3956         local mtime1=`stat -c %Y $DIR1/$tfile`
3957         [ "$mtime1" = $TEST_39_MTIME ] || \
3958                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3959
3960         local d1=`date +%s`
3961         echo hello >> $DIR1/$tfile
3962         local d2=`date +%s`
3963         local mtime2=`stat -c %Y $DIR1/$tfile`
3964         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3965                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3966
3967         mv $DIR1/$tfile $DIR1/$tfile-1
3968
3969         for (( i=0; i < 2; i++ )) ; do
3970                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3971                 [ "$mtime2" = "$mtime3" ] || \
3972                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3973
3974                 cancel_lru_locks $OSC
3975                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3976         done
3977 }
3978 run_test 39c "mtime change on rename ==========================="
3979
3980 # bug 21114
3981 test_39d() {
3982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3983
3984         touch $DIR1/$tfile
3985         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3986
3987         for (( i=0; i < 2; i++ )) ; do
3988                 local mtime=`stat -c %Y $DIR1/$tfile`
3989                 [ $mtime = $TEST_39_MTIME ] || \
3990                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3991
3992                 cancel_lru_locks $OSC
3993                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3994         done
3995 }
3996 run_test 39d "create, utime, stat =============================="
3997
3998 # bug 21114
3999 test_39e() {
4000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4001
4002         touch $DIR1/$tfile
4003         local mtime1=`stat -c %Y $DIR1/$tfile`
4004
4005         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4006
4007         for (( i=0; i < 2; i++ )) ; do
4008                 local mtime2=`stat -c %Y $DIR1/$tfile`
4009                 [ $mtime2 = $TEST_39_MTIME ] || \
4010                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4011
4012                 cancel_lru_locks $OSC
4013                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4014         done
4015 }
4016 run_test 39e "create, stat, utime, stat ========================"
4017
4018 # bug 21114
4019 test_39f() {
4020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4021
4022         touch $DIR1/$tfile
4023         mtime1=`stat -c %Y $DIR1/$tfile`
4024
4025         sleep 2
4026         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4027
4028         for (( i=0; i < 2; i++ )) ; do
4029                 local mtime2=`stat -c %Y $DIR1/$tfile`
4030                 [ $mtime2 = $TEST_39_MTIME ] || \
4031                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4032
4033                 cancel_lru_locks $OSC
4034                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4035         done
4036 }
4037 run_test 39f "create, stat, sleep, utime, stat ================="
4038
4039 # bug 11063
4040 test_39g() {
4041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4042
4043         echo hello >> $DIR1/$tfile
4044         local mtime1=`stat -c %Y $DIR1/$tfile`
4045
4046         sleep 2
4047         chmod o+r $DIR1/$tfile
4048
4049         for (( i=0; i < 2; i++ )) ; do
4050                 local mtime2=`stat -c %Y $DIR1/$tfile`
4051                 [ "$mtime1" = "$mtime2" ] || \
4052                         error "lost mtime: $mtime2, should be $mtime1"
4053
4054                 cancel_lru_locks $OSC
4055                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4056         done
4057 }
4058 run_test 39g "write, chmod, stat ==============================="
4059
4060 # bug 11063
4061 test_39h() {
4062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4063
4064         touch $DIR1/$tfile
4065         sleep 1
4066
4067         local d1=`date`
4068         echo hello >> $DIR1/$tfile
4069         local mtime1=`stat -c %Y $DIR1/$tfile`
4070
4071         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4072         local d2=`date`
4073         if [ "$d1" != "$d2" ]; then
4074                 echo "write and touch not within one second"
4075         else
4076                 for (( i=0; i < 2; i++ )) ; do
4077                         local mtime2=`stat -c %Y $DIR1/$tfile`
4078                         [ "$mtime2" = $TEST_39_MTIME ] || \
4079                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4080
4081                         cancel_lru_locks $OSC
4082                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4083                 done
4084         fi
4085 }
4086 run_test 39h "write, utime within one second, stat ============="
4087
4088 test_39i() {
4089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4090
4091         touch $DIR1/$tfile
4092         sleep 1
4093
4094         echo hello >> $DIR1/$tfile
4095         local mtime1=`stat -c %Y $DIR1/$tfile`
4096
4097         mv $DIR1/$tfile $DIR1/$tfile-1
4098
4099         for (( i=0; i < 2; i++ )) ; do
4100                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4101
4102                 [ "$mtime1" = "$mtime2" ] || \
4103                         error "lost mtime: $mtime2, should be $mtime1"
4104
4105                 cancel_lru_locks $OSC
4106                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4107         done
4108 }
4109 run_test 39i "write, rename, stat =============================="
4110
4111 test_39j() {
4112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4113
4114         start_full_debug_logging
4115         touch $DIR1/$tfile
4116         sleep 1
4117
4118         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4119         lctl set_param fail_loc=0x80000412
4120         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4121                 error "multiop failed"
4122         local multipid=$!
4123         local mtime1=`stat -c %Y $DIR1/$tfile`
4124
4125         mv $DIR1/$tfile $DIR1/$tfile-1
4126
4127         kill -USR1 $multipid
4128         wait $multipid || error "multiop close failed"
4129
4130         for (( i=0; i < 2; i++ )) ; do
4131                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4132                 [ "$mtime1" = "$mtime2" ] ||
4133                         error "mtime is lost on close: $mtime2, " \
4134                               "should be $mtime1"
4135
4136                 cancel_lru_locks $OSC
4137                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4138         done
4139         lctl set_param fail_loc=0
4140         stop_full_debug_logging
4141 }
4142 run_test 39j "write, rename, close, stat ======================="
4143
4144 test_39k() {
4145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4146
4147         touch $DIR1/$tfile
4148         sleep 1
4149
4150         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4151         local multipid=$!
4152         local mtime1=`stat -c %Y $DIR1/$tfile`
4153
4154         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4155
4156         kill -USR1 $multipid
4157         wait $multipid || error "multiop close failed"
4158
4159         for (( i=0; i < 2; i++ )) ; do
4160                 local mtime2=`stat -c %Y $DIR1/$tfile`
4161
4162                 [ "$mtime2" = $TEST_39_MTIME ] || \
4163                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4164
4165                 cancel_lru_locks osc
4166                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4167         done
4168 }
4169 run_test 39k "write, utime, close, stat ========================"
4170
4171 # this should be set to future
4172 TEST_39_ATIME=`date -d "1 year" +%s`
4173
4174 test_39l() {
4175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4176         remote_mds_nodsh && skip "remote MDS with nodsh"
4177
4178         local atime_diff=$(do_facet $SINGLEMDS \
4179                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4180         rm -rf $DIR/$tdir
4181         mkdir -p $DIR/$tdir
4182
4183         # test setting directory atime to future
4184         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4185         local atime=$(stat -c %X $DIR/$tdir)
4186         [ "$atime" = $TEST_39_ATIME ] ||
4187                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4188
4189         # test setting directory atime from future to now
4190         local now=$(date +%s)
4191         touch -a -d @$now $DIR/$tdir
4192
4193         atime=$(stat -c %X $DIR/$tdir)
4194         [ "$atime" -eq "$now"  ] ||
4195                 error "atime is not updated from future: $atime, $now"
4196
4197         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4198         sleep 3
4199
4200         # test setting directory atime when now > dir atime + atime_diff
4201         local d1=$(date +%s)
4202         ls $DIR/$tdir
4203         local d2=$(date +%s)
4204         cancel_lru_locks mdc
4205         atime=$(stat -c %X $DIR/$tdir)
4206         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4207                 error "atime is not updated  : $atime, should be $d2"
4208
4209         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4210         sleep 3
4211
4212         # test not setting directory atime when now < dir atime + atime_diff
4213         ls $DIR/$tdir
4214         cancel_lru_locks mdc
4215         atime=$(stat -c %X $DIR/$tdir)
4216         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4217                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4218
4219         do_facet $SINGLEMDS \
4220                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4221 }
4222 run_test 39l "directory atime update ==========================="
4223
4224 test_39m() {
4225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4226
4227         touch $DIR1/$tfile
4228         sleep 2
4229         local far_past_mtime=$(date -d "May 29 1953" +%s)
4230         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4231
4232         touch -m -d @$far_past_mtime $DIR1/$tfile
4233         touch -a -d @$far_past_atime $DIR1/$tfile
4234
4235         for (( i=0; i < 2; i++ )) ; do
4236                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4237                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4238                         error "atime or mtime set incorrectly"
4239
4240                 cancel_lru_locks $OSC
4241                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4242         done
4243 }
4244 run_test 39m "test atime and mtime before 1970"
4245
4246 test_39n() { # LU-3832
4247         remote_mds_nodsh && skip "remote MDS with nodsh"
4248
4249         local atime_diff=$(do_facet $SINGLEMDS \
4250                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4251         local atime0
4252         local atime1
4253         local atime2
4254
4255         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4256
4257         rm -rf $DIR/$tfile
4258         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4259         atime0=$(stat -c %X $DIR/$tfile)
4260
4261         sleep 5
4262         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4263         atime1=$(stat -c %X $DIR/$tfile)
4264
4265         sleep 5
4266         cancel_lru_locks mdc
4267         cancel_lru_locks osc
4268         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4269         atime2=$(stat -c %X $DIR/$tfile)
4270
4271         do_facet $SINGLEMDS \
4272                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4273
4274         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4275         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4276 }
4277 run_test 39n "check that O_NOATIME is honored"
4278
4279 test_39o() {
4280         TESTDIR=$DIR/$tdir/$tfile
4281         [ -e $TESTDIR ] && rm -rf $TESTDIR
4282         mkdir -p $TESTDIR
4283         cd $TESTDIR
4284         links1=2
4285         ls
4286         mkdir a b
4287         ls
4288         links2=$(stat -c %h .)
4289         [ $(($links1 + 2)) != $links2 ] &&
4290                 error "wrong links count $(($links1 + 2)) != $links2"
4291         rmdir b
4292         links3=$(stat -c %h .)
4293         [ $(($links1 + 1)) != $links3 ] &&
4294                 error "wrong links count $links1 != $links3"
4295         return 0
4296 }
4297 run_test 39o "directory cached attributes updated after create"
4298
4299 test_39p() {
4300         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4301
4302         local MDTIDX=1
4303         TESTDIR=$DIR/$tdir/$tdir
4304         [ -e $TESTDIR ] && rm -rf $TESTDIR
4305         test_mkdir -p $TESTDIR
4306         cd $TESTDIR
4307         links1=2
4308         ls
4309         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4310         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4311         ls
4312         links2=$(stat -c %h .)
4313         [ $(($links1 + 2)) != $links2 ] &&
4314                 error "wrong links count $(($links1 + 2)) != $links2"
4315         rmdir remote_dir2
4316         links3=$(stat -c %h .)
4317         [ $(($links1 + 1)) != $links3 ] &&
4318                 error "wrong links count $links1 != $links3"
4319         return 0
4320 }
4321 run_test 39p "remote directory cached attributes updated after create ========"
4322
4323
4324 test_39q() { # LU-8041
4325         local testdir=$DIR/$tdir
4326         mkdir -p $testdir
4327         multiop_bg_pause $testdir D_c || error "multiop failed"
4328         local multipid=$!
4329         cancel_lru_locks mdc
4330         kill -USR1 $multipid
4331         local atime=$(stat -c %X $testdir)
4332         [ "$atime" -ne 0 ] || error "atime is zero"
4333 }
4334 run_test 39q "close won't zero out atime"
4335
4336 test_40() {
4337         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4338         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4339                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4340         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4341                 error "$tfile is not 4096 bytes in size"
4342 }
4343 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4344
4345 test_41() {
4346         # bug 1553
4347         small_write $DIR/f41 18
4348 }
4349 run_test 41 "test small file write + fstat ====================="
4350
4351 count_ost_writes() {
4352         lctl get_param -n ${OSC}.*.stats |
4353                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4354                         END { printf("%0.0f", writes) }'
4355 }
4356
4357 # decent default
4358 WRITEBACK_SAVE=500
4359 DIRTY_RATIO_SAVE=40
4360 MAX_DIRTY_RATIO=50
4361 BG_DIRTY_RATIO_SAVE=10
4362 MAX_BG_DIRTY_RATIO=25
4363
4364 start_writeback() {
4365         trap 0
4366         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4367         # dirty_ratio, dirty_background_ratio
4368         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4369                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4370                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4371                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4372         else
4373                 # if file not here, we are a 2.4 kernel
4374                 kill -CONT `pidof kupdated`
4375         fi
4376 }
4377
4378 stop_writeback() {
4379         # setup the trap first, so someone cannot exit the test at the
4380         # exact wrong time and mess up a machine
4381         trap start_writeback EXIT
4382         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4383         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4384                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4385                 sysctl -w vm.dirty_writeback_centisecs=0
4386                 sysctl -w vm.dirty_writeback_centisecs=0
4387                 # save and increase /proc/sys/vm/dirty_ratio
4388                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4389                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4390                 # save and increase /proc/sys/vm/dirty_background_ratio
4391                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4392                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4393         else
4394                 # if file not here, we are a 2.4 kernel
4395                 kill -STOP `pidof kupdated`
4396         fi
4397 }
4398
4399 # ensure that all stripes have some grant before we test client-side cache
4400 setup_test42() {
4401         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4402                 dd if=/dev/zero of=$i bs=4k count=1
4403                 rm $i
4404         done
4405 }
4406
4407 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4408 # file truncation, and file removal.
4409 test_42a() {
4410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4411
4412         setup_test42
4413         cancel_lru_locks $OSC
4414         stop_writeback
4415         sync; sleep 1; sync # just to be safe
4416         BEFOREWRITES=`count_ost_writes`
4417         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4418         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4419         AFTERWRITES=`count_ost_writes`
4420         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4421                 error "$BEFOREWRITES < $AFTERWRITES"
4422         start_writeback
4423 }
4424 run_test 42a "ensure that we don't flush on close"
4425
4426 test_42b() {
4427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4428
4429         setup_test42
4430         cancel_lru_locks $OSC
4431         stop_writeback
4432         sync
4433         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4434         BEFOREWRITES=$(count_ost_writes)
4435         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4436         AFTERWRITES=$(count_ost_writes)
4437         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4438                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4439         fi
4440         BEFOREWRITES=$(count_ost_writes)
4441         sync || error "sync: $?"
4442         AFTERWRITES=$(count_ost_writes)
4443         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4444                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4445         fi
4446         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4447         start_writeback
4448         return 0
4449 }
4450 run_test 42b "test destroy of file with cached dirty data ======"
4451
4452 # if these tests just want to test the effect of truncation,
4453 # they have to be very careful.  consider:
4454 # - the first open gets a {0,EOF}PR lock
4455 # - the first write conflicts and gets a {0, count-1}PW
4456 # - the rest of the writes are under {count,EOF}PW
4457 # - the open for truncate tries to match a {0,EOF}PR
4458 #   for the filesize and cancels the PWs.
4459 # any number of fixes (don't get {0,EOF} on open, match
4460 # composite locks, do smarter file size management) fix
4461 # this, but for now we want these tests to verify that
4462 # the cancellation with truncate intent works, so we
4463 # start the file with a full-file pw lock to match against
4464 # until the truncate.
4465 trunc_test() {
4466         test=$1
4467         file=$DIR/$test
4468         offset=$2
4469         cancel_lru_locks $OSC
4470         stop_writeback
4471         # prime the file with 0,EOF PW to match
4472         touch $file
4473         $TRUNCATE $file 0
4474         sync; sync
4475         # now the real test..
4476         dd if=/dev/zero of=$file bs=1024 count=100
4477         BEFOREWRITES=`count_ost_writes`
4478         $TRUNCATE $file $offset
4479         cancel_lru_locks $OSC
4480         AFTERWRITES=`count_ost_writes`
4481         start_writeback
4482 }
4483
4484 test_42c() {
4485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4486
4487         trunc_test 42c 1024
4488         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4489                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4490         rm $file
4491 }
4492 run_test 42c "test partial truncate of file with cached dirty data"
4493
4494 test_42d() {
4495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4496
4497         trunc_test 42d 0
4498         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4499                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4500         rm $file
4501 }
4502 run_test 42d "test complete truncate of file with cached dirty data"
4503
4504 test_42e() { # bug22074
4505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4506
4507         local TDIR=$DIR/${tdir}e
4508         local pages=16 # hardcoded 16 pages, don't change it.
4509         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4510         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4511         local max_dirty_mb
4512         local warmup_files
4513
4514         test_mkdir $DIR/${tdir}e
4515         $LFS setstripe -c 1 $TDIR
4516         createmany -o $TDIR/f $files
4517
4518         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4519
4520         # we assume that with $OSTCOUNT files, at least one of them will
4521         # be allocated on OST0.
4522         warmup_files=$((OSTCOUNT * max_dirty_mb))
4523         createmany -o $TDIR/w $warmup_files
4524
4525         # write a large amount of data into one file and sync, to get good
4526         # avail_grant number from OST.
4527         for ((i=0; i<$warmup_files; i++)); do
4528                 idx=$($LFS getstripe -i $TDIR/w$i)
4529                 [ $idx -ne 0 ] && continue
4530                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4531                 break
4532         done
4533         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4534         sync
4535         $LCTL get_param $proc_osc0/cur_dirty_bytes
4536         $LCTL get_param $proc_osc0/cur_grant_bytes
4537
4538         # create as much dirty pages as we can while not to trigger the actual
4539         # RPCs directly. but depends on the env, VFS may trigger flush during this
4540         # period, hopefully we are good.
4541         for ((i=0; i<$warmup_files; i++)); do
4542                 idx=$($LFS getstripe -i $TDIR/w$i)
4543                 [ $idx -ne 0 ] && continue
4544                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4545         done
4546         $LCTL get_param $proc_osc0/cur_dirty_bytes
4547         $LCTL get_param $proc_osc0/cur_grant_bytes
4548
4549         # perform the real test
4550         $LCTL set_param $proc_osc0/rpc_stats 0
4551         for ((;i<$files; i++)); do
4552                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4553                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4554         done
4555         sync
4556         $LCTL get_param $proc_osc0/rpc_stats
4557
4558         local percent=0
4559         local have_ppr=false
4560         $LCTL get_param $proc_osc0/rpc_stats |
4561                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4562                         # skip lines until we are at the RPC histogram data
4563                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4564                         $have_ppr || continue
4565
4566                         # we only want the percent stat for < 16 pages
4567                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4568
4569                         percent=$((percent + WPCT))
4570                         if [[ $percent -gt 15 ]]; then
4571                                 error "less than 16-pages write RPCs" \
4572                                       "$percent% > 15%"
4573                                 break
4574                         fi
4575                 done
4576         rm -rf $TDIR
4577 }
4578 run_test 42e "verify sub-RPC writes are not done synchronously"
4579
4580 test_43A() { # was test_43
4581         test_mkdir $DIR/$tdir
4582         cp -p /bin/ls $DIR/$tdir/$tfile
4583         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4584         pid=$!
4585         # give multiop a chance to open
4586         sleep 1
4587
4588         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4589         kill -USR1 $pid
4590 }
4591 run_test 43A "execution of file opened for write should return -ETXTBSY"
4592
4593 test_43a() {
4594         test_mkdir $DIR/$tdir
4595         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4596         $DIR/$tdir/sleep 60 &
4597         SLEEP_PID=$!
4598         # Make sure exec of $tdir/sleep wins race with truncate
4599         sleep 1
4600         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4601         kill $SLEEP_PID
4602 }
4603 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4604
4605 test_43b() {
4606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4607
4608         test_mkdir $DIR/$tdir
4609         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4610         $DIR/$tdir/sleep 60 &
4611         SLEEP_PID=$!
4612         # Make sure exec of $tdir/sleep wins race with truncate
4613         sleep 1
4614         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4615         kill $SLEEP_PID
4616 }
4617 run_test 43b "truncate of file being executed should return -ETXTBSY"
4618
4619 test_43c() {
4620         local testdir="$DIR/$tdir"
4621         test_mkdir $testdir
4622         cp $SHELL $testdir/
4623         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4624                 ( cd $testdir && md5sum -c )
4625 }
4626 run_test 43c "md5sum of copy into lustre"
4627
4628 test_44A() { # was test_44
4629         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4630
4631         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4632         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4633 }
4634 run_test 44A "zero length read from a sparse stripe"
4635
4636 test_44a() {
4637         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4638                 awk '{ print $2 }')
4639         [ -z "$nstripe" ] && skip "can't get stripe info"
4640         [[ $nstripe -gt $OSTCOUNT ]] &&
4641                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4642
4643         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4644                 awk '{ print $2 }')
4645         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4646                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4647                         awk '{ print $2 }')
4648         fi
4649
4650         OFFSETS="0 $((stride/2)) $((stride-1))"
4651         for offset in $OFFSETS; do
4652                 for i in $(seq 0 $((nstripe-1))); do
4653                         local GLOBALOFFSETS=""
4654                         # size in Bytes
4655                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4656                         local myfn=$DIR/d44a-$size
4657                         echo "--------writing $myfn at $size"
4658                         ll_sparseness_write $myfn $size ||
4659                                 error "ll_sparseness_write"
4660                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4661                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4662                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4663
4664                         for j in $(seq 0 $((nstripe-1))); do
4665                                 # size in Bytes
4666                                 size=$((((j + $nstripe )*$stride + $offset)))
4667                                 ll_sparseness_write $myfn $size ||
4668                                         error "ll_sparseness_write"
4669                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4670                         done
4671                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4672                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4673                         rm -f $myfn
4674                 done
4675         done
4676 }
4677 run_test 44a "test sparse pwrite ==============================="
4678
4679 dirty_osc_total() {
4680         tot=0
4681         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4682                 tot=$(($tot + $d))
4683         done
4684         echo $tot
4685 }
4686 do_dirty_record() {
4687         before=`dirty_osc_total`
4688         echo executing "\"$*\""
4689         eval $*
4690         after=`dirty_osc_total`
4691         echo before $before, after $after
4692 }
4693 test_45() {
4694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4695
4696         f="$DIR/f45"
4697         # Obtain grants from OST if it supports it
4698         echo blah > ${f}_grant
4699         stop_writeback
4700         sync
4701         do_dirty_record "echo blah > $f"
4702         [[ $before -eq $after ]] && error "write wasn't cached"
4703         do_dirty_record "> $f"
4704         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4705         do_dirty_record "echo blah > $f"
4706         [[ $before -eq $after ]] && error "write wasn't cached"
4707         do_dirty_record "sync"
4708         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4709         do_dirty_record "echo blah > $f"
4710         [[ $before -eq $after ]] && error "write wasn't cached"
4711         do_dirty_record "cancel_lru_locks osc"
4712         [[ $before -gt $after ]] ||
4713                 error "lock cancellation didn't lower dirty count"
4714         start_writeback
4715 }
4716 run_test 45 "osc io page accounting ============================"
4717
4718 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4719 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4720 # objects offset and an assert hit when an rpc was built with 1023's mapped
4721 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4722 test_46() {
4723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4724
4725         f="$DIR/f46"
4726         stop_writeback
4727         sync
4728         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4729         sync
4730         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4731         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4732         sync
4733         start_writeback
4734 }
4735 run_test 46 "dirtying a previously written page ================"
4736
4737 # test_47 is removed "Device nodes check" is moved to test_28
4738
4739 test_48a() { # bug 2399
4740         [ "$mds1_FSTYPE" = "zfs" ] &&
4741         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4742                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4743
4744         test_mkdir $DIR/$tdir
4745         cd $DIR/$tdir
4746         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4747         test_mkdir $DIR/$tdir
4748         touch foo || error "'touch foo' failed after recreating cwd"
4749         test_mkdir bar
4750         touch .foo || error "'touch .foo' failed after recreating cwd"
4751         test_mkdir .bar
4752         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4753         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4754         cd . || error "'cd .' failed after recreating cwd"
4755         mkdir . && error "'mkdir .' worked after recreating cwd"
4756         rmdir . && error "'rmdir .' worked after recreating cwd"
4757         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4758         cd .. || error "'cd ..' failed after recreating cwd"
4759 }
4760 run_test 48a "Access renamed working dir (should return errors)="
4761
4762 test_48b() { # bug 2399
4763         rm -rf $DIR/$tdir
4764         test_mkdir $DIR/$tdir
4765         cd $DIR/$tdir
4766         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4767         touch foo && error "'touch foo' worked after removing cwd"
4768         mkdir foo && error "'mkdir foo' worked after removing cwd"
4769         touch .foo && error "'touch .foo' worked after removing cwd"
4770         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4771         ls . > /dev/null && error "'ls .' worked after removing cwd"
4772         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4773         mkdir . && error "'mkdir .' worked after removing cwd"
4774         rmdir . && error "'rmdir .' worked after removing cwd"
4775         ln -s . foo && error "'ln -s .' worked after removing cwd"
4776         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4777 }
4778 run_test 48b "Access removed working dir (should return errors)="
4779
4780 test_48c() { # bug 2350
4781         #lctl set_param debug=-1
4782         #set -vx
4783         rm -rf $DIR/$tdir
4784         test_mkdir -p $DIR/$tdir/dir
4785         cd $DIR/$tdir/dir
4786         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4787         $TRACE touch foo && error "touch foo worked after removing cwd"
4788         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4789         touch .foo && error "touch .foo worked after removing cwd"
4790         mkdir .foo && error "mkdir .foo worked after removing cwd"
4791         $TRACE ls . && error "'ls .' worked after removing cwd"
4792         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4793         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4794         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4795         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4796         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4797 }
4798 run_test 48c "Access removed working subdir (should return errors)"
4799
4800 test_48d() { # bug 2350
4801         #lctl set_param debug=-1
4802         #set -vx
4803         rm -rf $DIR/$tdir
4804         test_mkdir -p $DIR/$tdir/dir
4805         cd $DIR/$tdir/dir
4806         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4807         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4808         $TRACE touch foo && error "'touch foo' worked after removing parent"
4809         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4810         touch .foo && error "'touch .foo' worked after removing parent"
4811         mkdir .foo && error "mkdir .foo worked after removing parent"
4812         $TRACE ls . && error "'ls .' worked after removing parent"
4813         $TRACE ls .. && error "'ls ..' worked after removing parent"
4814         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4815         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4816         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4817         true
4818 }
4819 run_test 48d "Access removed parent subdir (should return errors)"
4820
4821 test_48e() { # bug 4134
4822         #lctl set_param debug=-1
4823         #set -vx
4824         rm -rf $DIR/$tdir
4825         test_mkdir -p $DIR/$tdir/dir
4826         cd $DIR/$tdir/dir
4827         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4828         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4829         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4830         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4831         # On a buggy kernel addition of "touch foo" after cd .. will
4832         # produce kernel oops in lookup_hash_it
4833         touch ../foo && error "'cd ..' worked after recreate parent"
4834         cd $DIR
4835         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4836 }
4837 run_test 48e "Access to recreated parent subdir (should return errors)"
4838
4839 test_49() { # LU-1030
4840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4841         remote_ost_nodsh && skip "remote OST with nodsh"
4842
4843         # get ost1 size - lustre-OST0000
4844         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4845                 awk '{ print $4 }')
4846         # write 800M at maximum
4847         [[ $ost1_size -lt 2 ]] && ost1_size=2
4848         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4849
4850         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4851         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4852         local dd_pid=$!
4853
4854         # change max_pages_per_rpc while writing the file
4855         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4856         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4857         # loop until dd process exits
4858         while ps ax -opid | grep -wq $dd_pid; do
4859                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4860                 sleep $((RANDOM % 5 + 1))
4861         done
4862         # restore original max_pages_per_rpc
4863         $LCTL set_param $osc1_mppc=$orig_mppc
4864         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4865 }
4866 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4867
4868 test_50() {
4869         # bug 1485
4870         test_mkdir $DIR/$tdir
4871         cd $DIR/$tdir
4872         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4873 }
4874 run_test 50 "special situations: /proc symlinks  ==============="
4875
4876 test_51a() {    # was test_51
4877         # bug 1516 - create an empty entry right after ".." then split dir
4878         test_mkdir -c1 $DIR/$tdir
4879         touch $DIR/$tdir/foo
4880         $MCREATE $DIR/$tdir/bar
4881         rm $DIR/$tdir/foo
4882         createmany -m $DIR/$tdir/longfile 201
4883         FNUM=202
4884         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4885                 $MCREATE $DIR/$tdir/longfile$FNUM
4886                 FNUM=$(($FNUM + 1))
4887                 echo -n "+"
4888         done
4889         echo
4890         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4891 }
4892 run_test 51a "special situations: split htree with empty entry =="
4893
4894 cleanup_print_lfs_df () {
4895         trap 0
4896         $LFS df
4897         $LFS df -i
4898 }
4899
4900 test_51b() {
4901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4902
4903         local dir=$DIR/$tdir
4904         local nrdirs=$((65536 + 100))
4905
4906         # cleanup the directory
4907         rm -fr $dir
4908
4909         test_mkdir -c1 $dir
4910
4911         $LFS df
4912         $LFS df -i
4913         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4914         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4915         [[ $numfree -lt $nrdirs ]] &&
4916                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4917
4918         # need to check free space for the directories as well
4919         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4920         numfree=$(( blkfree / $(fs_inode_ksize) ))
4921         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4922
4923         trap cleanup_print_lfs_df EXIT
4924
4925         # create files
4926         createmany -d $dir/d $nrdirs || {
4927                 unlinkmany $dir/d $nrdirs
4928                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4929         }
4930
4931         # really created :
4932         nrdirs=$(ls -U $dir | wc -l)
4933
4934         # unlink all but 100 subdirectories, then check it still works
4935         local left=100
4936         local delete=$((nrdirs - left))
4937
4938         $LFS df
4939         $LFS df -i
4940
4941         # for ldiskfs the nlink count should be 1, but this is OSD specific
4942         # and so this is listed for informational purposes only
4943         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4944         unlinkmany -d $dir/d $delete ||
4945                 error "unlink of first $delete subdirs failed"
4946
4947         echo "nlink between: $(stat -c %h $dir)"
4948         local found=$(ls -U $dir | wc -l)
4949         [ $found -ne $left ] &&
4950                 error "can't find subdirs: found only $found, expected $left"
4951
4952         unlinkmany -d $dir/d $delete $left ||
4953                 error "unlink of second $left subdirs failed"
4954         # regardless of whether the backing filesystem tracks nlink accurately
4955         # or not, the nlink count shouldn't be more than "." and ".." here
4956         local after=$(stat -c %h $dir)
4957         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4958                 echo "nlink after: $after"
4959
4960         cleanup_print_lfs_df
4961 }
4962 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4963
4964 test_51d() {
4965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4966         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4967
4968         test_mkdir $DIR/$tdir
4969         createmany -o $DIR/$tdir/t- 1000
4970         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4971         for N in $(seq 0 $((OSTCOUNT - 1))); do
4972                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4973                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4974                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4975                         '($1 == '$N') { objs += 1 } \
4976                         END { printf("%0.0f", objs) }')
4977                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4978         done
4979         unlinkmany $DIR/$tdir/t- 1000
4980
4981         NLAST=0
4982         for N in $(seq 1 $((OSTCOUNT - 1))); do
4983                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4984                         error "OST $N has less objects vs OST $NLAST" \
4985                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4986                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4987                         error "OST $N has less objects vs OST $NLAST" \
4988                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4989
4990                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4991                         error "OST $N has less #0 objects vs OST $NLAST" \
4992                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4993                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4994                         error "OST $N has less #0 objects vs OST $NLAST" \
4995                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4996                 NLAST=$N
4997         done
4998         rm -f $TMP/$tfile
4999 }
5000 run_test 51d "check object distribution"
5001
5002 test_51e() {
5003         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5004                 skip_env "ldiskfs only test"
5005         fi
5006
5007         test_mkdir -c1 $DIR/$tdir
5008         test_mkdir -c1 $DIR/$tdir/d0
5009
5010         touch $DIR/$tdir/d0/foo
5011         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5012                 error "file exceed 65000 nlink limit!"
5013         unlinkmany $DIR/$tdir/d0/f- 65001
5014         return 0
5015 }
5016 run_test 51e "check file nlink limit"
5017
5018 test_51f() {
5019         test_mkdir $DIR/$tdir
5020
5021         local max=100000
5022         local ulimit_old=$(ulimit -n)
5023         local spare=20 # number of spare fd's for scripts/libraries, etc.
5024         local mdt=$($LFS getstripe -m $DIR/$tdir)
5025         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5026
5027         echo "MDT$mdt numfree=$numfree, max=$max"
5028         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5029         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5030                 while ! ulimit -n $((numfree + spare)); do
5031                         numfree=$((numfree * 3 / 4))
5032                 done
5033                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5034         else
5035                 echo "left ulimit at $ulimit_old"
5036         fi
5037
5038         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5039                 unlinkmany $DIR/$tdir/f $numfree
5040                 error "create+open $numfree files in $DIR/$tdir failed"
5041         }
5042         ulimit -n $ulimit_old
5043
5044         # if createmany exits at 120s there will be fewer than $numfree files
5045         unlinkmany $DIR/$tdir/f $numfree || true
5046 }
5047 run_test 51f "check many open files limit"
5048
5049 test_52a() {
5050         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5051         test_mkdir $DIR/$tdir
5052         touch $DIR/$tdir/foo
5053         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5054         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5055         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5056         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5057         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5058                                         error "link worked"
5059         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5060         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5061         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5062                                                      error "lsattr"
5063         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5064         cp -r $DIR/$tdir $TMP/
5065         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5066 }
5067 run_test 52a "append-only flag test (should return errors)"
5068
5069 test_52b() {
5070         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5071         test_mkdir $DIR/$tdir
5072         touch $DIR/$tdir/foo
5073         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5074         cat test > $DIR/$tdir/foo && error "cat test worked"
5075         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5076         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5077         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5078                                         error "link worked"
5079         echo foo >> $DIR/$tdir/foo && error "echo worked"
5080         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5081         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5082         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5083         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5084                                                         error "lsattr"
5085         chattr -i $DIR/$tdir/foo || error "chattr failed"
5086
5087         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5088 }
5089 run_test 52b "immutable flag test (should return errors) ======="
5090
5091 test_53() {
5092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5093         remote_mds_nodsh && skip "remote MDS with nodsh"
5094         remote_ost_nodsh && skip "remote OST with nodsh"
5095
5096         local param
5097         local param_seq
5098         local ostname
5099         local mds_last
5100         local mds_last_seq
5101         local ost_last
5102         local ost_last_seq
5103         local ost_last_id
5104         local ostnum
5105         local node
5106         local found=false
5107         local support_last_seq=true
5108
5109         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5110                 support_last_seq=false
5111
5112         # only test MDT0000
5113         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5114         local value
5115         for value in $(do_facet $SINGLEMDS \
5116                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5117                 param=$(echo ${value[0]} | cut -d "=" -f1)
5118                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5119
5120                 if $support_last_seq; then
5121                         param_seq=$(echo $param |
5122                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5123                         mds_last_seq=$(do_facet $SINGLEMDS \
5124                                        $LCTL get_param -n $param_seq)
5125                 fi
5126                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5127
5128                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5129                 node=$(facet_active_host ost$((ostnum+1)))
5130                 param="obdfilter.$ostname.last_id"
5131                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5132                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5133                         ost_last_id=$ost_last
5134
5135                         if $support_last_seq; then
5136                                 ost_last_id=$(echo $ost_last |
5137                                               awk -F':' '{print $2}' |
5138                                               sed -e "s/^0x//g")
5139                                 ost_last_seq=$(echo $ost_last |
5140                                                awk -F':' '{print $1}')
5141                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5142                         fi
5143
5144                         if [[ $ost_last_id != $mds_last ]]; then
5145                                 error "$ost_last_id != $mds_last"
5146                         else
5147                                 found=true
5148                                 break
5149                         fi
5150                 done
5151         done
5152         $found || error "can not match last_seq/last_id for $mdtosc"
5153         return 0
5154 }
5155 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5156
5157 test_54a() {
5158         perl -MSocket -e ';' || skip "no Socket perl module installed"
5159
5160         $SOCKETSERVER $DIR/socket ||
5161                 error "$SOCKETSERVER $DIR/socket failed: $?"
5162         $SOCKETCLIENT $DIR/socket ||
5163                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5164         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5165 }
5166 run_test 54a "unix domain socket test =========================="
5167
5168 test_54b() {
5169         f="$DIR/f54b"
5170         mknod $f c 1 3
5171         chmod 0666 $f
5172         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5173 }
5174 run_test 54b "char device works in lustre ======================"
5175
5176 find_loop_dev() {
5177         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5178         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5179         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5180
5181         for i in $(seq 3 7); do
5182                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5183                 LOOPDEV=$LOOPBASE$i
5184                 LOOPNUM=$i
5185                 break
5186         done
5187 }
5188
5189 cleanup_54c() {
5190         local rc=0
5191         loopdev="$DIR/loop54c"
5192
5193         trap 0
5194         $UMOUNT $DIR/$tdir || rc=$?
5195         losetup -d $loopdev || true
5196         losetup -d $LOOPDEV || true
5197         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5198         return $rc
5199 }
5200
5201 test_54c() {
5202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5203
5204         loopdev="$DIR/loop54c"
5205
5206         find_loop_dev
5207         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5208         trap cleanup_54c EXIT
5209         mknod $loopdev b 7 $LOOPNUM
5210         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5211         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5212         losetup $loopdev $DIR/$tfile ||
5213                 error "can't set up $loopdev for $DIR/$tfile"
5214         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5215         test_mkdir $DIR/$tdir
5216         mount -t ext2 $loopdev $DIR/$tdir ||
5217                 error "error mounting $loopdev on $DIR/$tdir"
5218         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5219                 error "dd write"
5220         df $DIR/$tdir
5221         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5222                 error "dd read"
5223         cleanup_54c
5224 }
5225 run_test 54c "block device works in lustre ====================="
5226
5227 test_54d() {
5228         f="$DIR/f54d"
5229         string="aaaaaa"
5230         mknod $f p
5231         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5232 }
5233 run_test 54d "fifo device works in lustre ======================"
5234
5235 test_54e() {
5236         f="$DIR/f54e"
5237         string="aaaaaa"
5238         cp -aL /dev/console $f
5239         echo $string > $f || error "echo $string to $f failed"
5240 }
5241 run_test 54e "console/tty device works in lustre ======================"
5242
5243 test_56a() {
5244         local numfiles=3
5245         local dir=$DIR/$tdir
5246
5247         rm -rf $dir
5248         test_mkdir -p $dir/dir
5249         for i in $(seq $numfiles); do
5250                 touch $dir/file$i
5251                 touch $dir/dir/file$i
5252         done
5253
5254         local numcomp=$($LFS getstripe --component-count $dir)
5255
5256         [[ $numcomp == 0 ]] && numcomp=1
5257
5258         # test lfs getstripe with --recursive
5259         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5260
5261         [[ $filenum -eq $((numfiles * 2)) ]] ||
5262                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5263         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5264         [[ $filenum -eq $numfiles ]] ||
5265                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5266         echo "$LFS getstripe showed obdidx or l_ost_idx"
5267
5268         # test lfs getstripe with file instead of dir
5269         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5270         [[ $filenum -eq 1 ]] ||
5271                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5272         echo "$LFS getstripe file1 passed"
5273
5274         #test lfs getstripe with --verbose
5275         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5276         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5277                 error "$LFS getstripe --verbose $dir: "\
5278                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5279         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5280                 error "$LFS getstripe $dir: showed lmm_magic"
5281
5282         #test lfs getstripe with -v prints lmm_fid
5283         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5284         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5285                 error "$LFS getstripe -v $dir: "\
5286                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5287         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5288                 error "$LFS getstripe $dir: showed lmm_fid by default"
5289         echo "$LFS getstripe --verbose passed"
5290
5291         #check for FID information
5292         local fid1=$($LFS getstripe --fid $dir/file1)
5293         local fid2=$($LFS getstripe --verbose $dir/file1 |
5294                      awk '/lmm_fid: / { print $2; exit; }')
5295         local fid3=$($LFS path2fid $dir/file1)
5296
5297         [ "$fid1" != "$fid2" ] &&
5298                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5299         [ "$fid1" != "$fid3" ] &&
5300                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5301         echo "$LFS getstripe --fid passed"
5302
5303         #test lfs getstripe with --obd
5304         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5305                 error "$LFS getstripe --obd wrong_uuid: should return error"
5306
5307         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5308
5309         local ostidx=1
5310         local obduuid=$(ostuuid_from_index $ostidx)
5311         local found=$($LFS getstripe -r --obd $obduuid $dir |
5312                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5313
5314         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5315         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5316                 ((filenum--))
5317         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5318                 ((filenum--))
5319
5320         [[ $found -eq $filenum ]] ||
5321                 error "$LFS getstripe --obd: found $found expect $filenum"
5322         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5323                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5324                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5325                 error "$LFS getstripe --obd: should not show file on other obd"
5326         echo "$LFS getstripe --obd passed"
5327 }
5328 run_test 56a "check $LFS getstripe"
5329
5330 test_56b() {
5331         local dir=$DIR/$tdir
5332         local numdirs=3
5333
5334         test_mkdir $dir
5335         for i in $(seq $numdirs); do
5336                 test_mkdir $dir/dir$i
5337         done
5338
5339         # test lfs getdirstripe default mode is non-recursion, which is
5340         # different from lfs getstripe
5341         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5342
5343         [[ $dircnt -eq 1 ]] ||
5344                 error "$LFS getdirstripe: found $dircnt, not 1"
5345         dircnt=$($LFS getdirstripe --recursive $dir |
5346                 grep -c lmv_stripe_count)
5347         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5348                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5349 }
5350 run_test 56b "check $LFS getdirstripe"
5351
5352 test_56c() {
5353         remote_ost_nodsh && skip "remote OST with nodsh"
5354
5355         local ost_idx=0
5356         local ost_name=$(ostname_from_index $ost_idx)
5357         local old_status=$(ost_dev_status $ost_idx)
5358
5359         [[ -z "$old_status" ]] ||
5360                 skip_env "OST $ost_name is in $old_status status"
5361
5362         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5363         sleep_maxage
5364
5365         local new_status=$(ost_dev_status $ost_idx)
5366
5367         [[ "$new_status" = "D" ]] ||
5368                 error "OST $ost_name is in status of '$new_status', not 'D'"
5369
5370         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5371         sleep_maxage
5372
5373         new_status=$(ost_dev_status $ost_idx)
5374         [[ -z "$new_status" ]] ||
5375                 error "OST $ost_name is in status of '$new_status', not ''"
5376 }
5377 run_test 56c "check 'lfs df' showing device status"
5378
5379 NUMFILES=3
5380 NUMDIRS=3
5381 setup_56() {
5382         local local_tdir="$1"
5383         local local_numfiles="$2"
5384         local local_numdirs="$3"
5385         local dir_params="$4"
5386         local dir_stripe_params="$5"
5387
5388         if [ ! -d "$local_tdir" ] ; then
5389                 test_mkdir -p $dir_stripe_params $local_tdir
5390                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5391                 for i in $(seq $local_numfiles) ; do
5392                         touch $local_tdir/file$i
5393                 done
5394                 for i in $(seq $local_numdirs) ; do
5395                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5396                         for j in $(seq $local_numfiles) ; do
5397                                 touch $local_tdir/dir$i/file$j
5398                         done
5399                 done
5400         fi
5401 }
5402
5403 setup_56_special() {
5404         local local_tdir=$1
5405         local local_numfiles=$2
5406         local local_numdirs=$3
5407
5408         setup_56 $local_tdir $local_numfiles $local_numdirs
5409
5410         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5411                 for i in $(seq $local_numfiles) ; do
5412                         mknod $local_tdir/loop${i}b b 7 $i
5413                         mknod $local_tdir/null${i}c c 1 3
5414                         ln -s $local_tdir/file1 $local_tdir/link${i}
5415                 done
5416                 for i in $(seq $local_numdirs) ; do
5417                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5418                         mknod $local_tdir/dir$i/null${i}c c 1 3
5419                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5420                 done
5421         fi
5422 }
5423
5424 test_56g() {
5425         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5426         local expected=$(($NUMDIRS + 2))
5427
5428         setup_56 $dir $NUMFILES $NUMDIRS
5429
5430         # test lfs find with -name
5431         for i in $(seq $NUMFILES) ; do
5432                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5433
5434                 [ $nums -eq $expected ] ||
5435                         error "lfs find -name '*$i' $dir wrong: "\
5436                               "found $nums, expected $expected"
5437         done
5438 }
5439 run_test 56g "check lfs find -name"
5440
5441 test_56h() {
5442         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5443         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5444
5445         setup_56 $dir $NUMFILES $NUMDIRS
5446
5447         # test lfs find with ! -name
5448         for i in $(seq $NUMFILES) ; do
5449                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5450
5451                 [ $nums -eq $expected ] ||
5452                         error "lfs find ! -name '*$i' $dir wrong: "\
5453                               "found $nums, expected $expected"
5454         done
5455 }
5456 run_test 56h "check lfs find ! -name"
5457
5458 test_56i() {
5459         local dir=$DIR/$tdir
5460
5461         test_mkdir $dir
5462
5463         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5464         local out=$($cmd)
5465
5466         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5467 }
5468 run_test 56i "check 'lfs find -ost UUID' skips directories"
5469
5470 test_56j() {
5471         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5472
5473         setup_56_special $dir $NUMFILES $NUMDIRS
5474
5475         local expected=$((NUMDIRS + 1))
5476         local cmd="$LFS find -type d $dir"
5477         local nums=$($cmd | wc -l)
5478
5479         [ $nums -eq $expected ] ||
5480                 error "'$cmd' wrong: found $nums, expected $expected"
5481 }
5482 run_test 56j "check lfs find -type d"
5483
5484 test_56k() {
5485         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5486
5487         setup_56_special $dir $NUMFILES $NUMDIRS
5488
5489         local expected=$(((NUMDIRS + 1) * NUMFILES))
5490         local cmd="$LFS find -type f $dir"
5491         local nums=$($cmd | wc -l)
5492
5493         [ $nums -eq $expected ] ||
5494                 error "'$cmd' wrong: found $nums, expected $expected"
5495 }
5496 run_test 56k "check lfs find -type f"
5497
5498 test_56l() {
5499         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5500
5501         setup_56_special $dir $NUMFILES $NUMDIRS
5502
5503         local expected=$((NUMDIRS + NUMFILES))
5504         local cmd="$LFS find -type b $dir"
5505         local nums=$($cmd | wc -l)
5506
5507         [ $nums -eq $expected ] ||
5508                 error "'$cmd' wrong: found $nums, expected $expected"
5509 }
5510 run_test 56l "check lfs find -type b"
5511
5512 test_56m() {
5513         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5514
5515         setup_56_special $dir $NUMFILES $NUMDIRS
5516
5517         local expected=$((NUMDIRS + NUMFILES))
5518         local cmd="$LFS find -type c $dir"
5519         local nums=$($cmd | wc -l)
5520         [ $nums -eq $expected ] ||
5521                 error "'$cmd' wrong: found $nums, expected $expected"
5522 }
5523 run_test 56m "check lfs find -type c"
5524
5525 test_56n() {
5526         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5527         setup_56_special $dir $NUMFILES $NUMDIRS
5528
5529         local expected=$((NUMDIRS + NUMFILES))
5530         local cmd="$LFS find -type l $dir"
5531         local nums=$($cmd | wc -l)
5532
5533         [ $nums -eq $expected ] ||
5534                 error "'$cmd' wrong: found $nums, expected $expected"
5535 }
5536 run_test 56n "check lfs find -type l"
5537
5538 test_56o() {
5539         local dir=$DIR/$tdir
5540
5541         setup_56 $dir $NUMFILES $NUMDIRS
5542         utime $dir/file1 > /dev/null || error "utime (1)"
5543         utime $dir/file2 > /dev/null || error "utime (2)"
5544         utime $dir/dir1 > /dev/null || error "utime (3)"
5545         utime $dir/dir2 > /dev/null || error "utime (4)"
5546         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5547         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5548
5549         local expected=4
5550         local nums=$($LFS find -mtime +0 $dir | wc -l)
5551
5552         [ $nums -eq $expected ] ||
5553                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5554
5555         expected=12
5556         cmd="$LFS find -mtime 0 $dir"
5557         nums=$($cmd | wc -l)
5558         [ $nums -eq $expected ] ||
5559                 error "'$cmd' wrong: found $nums, expected $expected"
5560 }
5561 run_test 56o "check lfs find -mtime for old files"
5562
5563 test_56ob() {
5564         local dir=$DIR/$tdir
5565         local expected=1
5566         local count=0
5567
5568         # just to make sure there is something that won't be found
5569         test_mkdir $dir
5570         touch $dir/$tfile.now
5571
5572         for age in year week day hour min; do
5573                 count=$((count + 1))
5574
5575                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5576                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5577                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5578
5579                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5580                 local nums=$($cmd | wc -l)
5581                 [ $nums -eq $expected ] ||
5582                         error "'$cmd' wrong: found $nums, expected $expected"
5583
5584                 cmd="$LFS find $dir -atime $count${age:0:1}"
5585                 nums=$($cmd | wc -l)
5586                 [ $nums -eq $expected ] ||
5587                         error "'$cmd' wrong: found $nums, expected $expected"
5588         done
5589
5590         sleep 2
5591         cmd="$LFS find $dir -ctime +1s -type f"
5592         nums=$($cmd | wc -l)
5593         (( $nums == $count * 2 + 1)) ||
5594                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5595 }
5596 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5597
5598 test_56p() {
5599         [ $RUNAS_ID -eq $UID ] &&
5600                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5601
5602         local dir=$DIR/$tdir
5603
5604         setup_56 $dir $NUMFILES $NUMDIRS
5605         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5606
5607         local expected=$NUMFILES
5608         local cmd="$LFS find -uid $RUNAS_ID $dir"
5609         local nums=$($cmd | wc -l)
5610
5611         [ $nums -eq $expected ] ||
5612                 error "'$cmd' wrong: found $nums, expected $expected"
5613
5614         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5615         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5616         nums=$($cmd | wc -l)
5617         [ $nums -eq $expected ] ||
5618                 error "'$cmd' wrong: found $nums, expected $expected"
5619 }
5620 run_test 56p "check lfs find -uid and ! -uid"
5621
5622 test_56q() {
5623         [ $RUNAS_ID -eq $UID ] &&
5624                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5625
5626         local dir=$DIR/$tdir
5627
5628         setup_56 $dir $NUMFILES $NUMDIRS
5629         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5630
5631         local expected=$NUMFILES
5632         local cmd="$LFS find -gid $RUNAS_GID $dir"
5633         local nums=$($cmd | wc -l)
5634
5635         [ $nums -eq $expected ] ||
5636                 error "'$cmd' wrong: found $nums, expected $expected"
5637
5638         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5639         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5640         nums=$($cmd | wc -l)
5641         [ $nums -eq $expected ] ||
5642                 error "'$cmd' wrong: found $nums, expected $expected"
5643 }
5644 run_test 56q "check lfs find -gid and ! -gid"
5645
5646 test_56r() {
5647         local dir=$DIR/$tdir
5648
5649         setup_56 $dir $NUMFILES $NUMDIRS
5650
5651         local expected=12
5652         local cmd="$LFS find -size 0 -type f $dir"
5653         local nums=$($cmd | wc -l)
5654
5655         [ $nums -eq $expected ] ||
5656                 error "'$cmd' wrong: found $nums, expected $expected"
5657         expected=0
5658         cmd="$LFS find ! -size 0 -type f $dir"
5659         nums=$($cmd | wc -l)
5660         [ $nums -eq $expected ] ||
5661                 error "'$cmd' wrong: found $nums, expected $expected"
5662         echo "test" > $dir/$tfile
5663         echo "test2" > $dir/$tfile.2 && sync
5664         expected=1
5665         cmd="$LFS find -size 5 -type f $dir"
5666         nums=$($cmd | wc -l)
5667         [ $nums -eq $expected ] ||
5668                 error "'$cmd' wrong: found $nums, expected $expected"
5669         expected=1
5670         cmd="$LFS find -size +5 -type f $dir"
5671         nums=$($cmd | wc -l)
5672         [ $nums -eq $expected ] ||
5673                 error "'$cmd' wrong: found $nums, expected $expected"
5674         expected=2
5675         cmd="$LFS find -size +0 -type f $dir"
5676         nums=$($cmd | wc -l)
5677         [ $nums -eq $expected ] ||
5678                 error "'$cmd' wrong: found $nums, expected $expected"
5679         expected=2
5680         cmd="$LFS find ! -size -5 -type f $dir"
5681         nums=$($cmd | wc -l)
5682         [ $nums -eq $expected ] ||
5683                 error "'$cmd' wrong: found $nums, expected $expected"
5684         expected=12
5685         cmd="$LFS find -size -5 -type f $dir"
5686         nums=$($cmd | wc -l)
5687         [ $nums -eq $expected ] ||
5688                 error "'$cmd' wrong: found $nums, expected $expected"
5689 }
5690 run_test 56r "check lfs find -size works"
5691
5692 test_56s() { # LU-611 #LU-9369
5693         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5694
5695         local dir=$DIR/$tdir
5696         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5697
5698         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5699         for i in $(seq $NUMDIRS); do
5700                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5701         done
5702
5703         local expected=$NUMDIRS
5704         local cmd="$LFS find -c $OSTCOUNT $dir"
5705         local nums=$($cmd | wc -l)
5706
5707         [ $nums -eq $expected ] || {
5708                 $LFS getstripe -R $dir
5709                 error "'$cmd' wrong: found $nums, expected $expected"
5710         }
5711
5712         expected=$((NUMDIRS + onestripe))
5713         cmd="$LFS find -stripe-count +0 -type f $dir"
5714         nums=$($cmd | wc -l)
5715         [ $nums -eq $expected ] || {
5716                 $LFS getstripe -R $dir
5717                 error "'$cmd' wrong: found $nums, expected $expected"
5718         }
5719
5720         expected=$onestripe
5721         cmd="$LFS find -stripe-count 1 -type f $dir"
5722         nums=$($cmd | wc -l)
5723         [ $nums -eq $expected ] || {
5724                 $LFS getstripe -R $dir
5725                 error "'$cmd' wrong: found $nums, expected $expected"
5726         }
5727
5728         cmd="$LFS find -stripe-count -2 -type f $dir"
5729         nums=$($cmd | wc -l)
5730         [ $nums -eq $expected ] || {
5731                 $LFS getstripe -R $dir
5732                 error "'$cmd' wrong: found $nums, expected $expected"
5733         }
5734
5735         expected=0
5736         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5737         nums=$($cmd | wc -l)
5738         [ $nums -eq $expected ] || {
5739                 $LFS getstripe -R $dir
5740                 error "'$cmd' wrong: found $nums, expected $expected"
5741         }
5742 }
5743 run_test 56s "check lfs find -stripe-count works"
5744
5745 test_56t() { # LU-611 #LU-9369
5746         local dir=$DIR/$tdir
5747
5748         setup_56 $dir 0 $NUMDIRS
5749         for i in $(seq $NUMDIRS); do
5750                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5751         done
5752
5753         local expected=$NUMDIRS
5754         local cmd="$LFS find -S 8M $dir"
5755         local nums=$($cmd | wc -l)
5756
5757         [ $nums -eq $expected ] || {
5758                 $LFS getstripe -R $dir
5759                 error "'$cmd' wrong: found $nums, expected $expected"
5760         }
5761         rm -rf $dir
5762
5763         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5764
5765         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5766
5767         expected=$(((NUMDIRS + 1) * NUMFILES))
5768         cmd="$LFS find -stripe-size 512k -type f $dir"
5769         nums=$($cmd | wc -l)
5770         [ $nums -eq $expected ] ||
5771                 error "'$cmd' wrong: found $nums, expected $expected"
5772
5773         cmd="$LFS find -stripe-size +320k -type f $dir"
5774         nums=$($cmd | wc -l)
5775         [ $nums -eq $expected ] ||
5776                 error "'$cmd' wrong: found $nums, expected $expected"
5777
5778         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5779         cmd="$LFS find -stripe-size +200k -type f $dir"
5780         nums=$($cmd | wc -l)
5781         [ $nums -eq $expected ] ||
5782                 error "'$cmd' wrong: found $nums, expected $expected"
5783
5784         cmd="$LFS find -stripe-size -640k -type f $dir"
5785         nums=$($cmd | wc -l)
5786         [ $nums -eq $expected ] ||
5787                 error "'$cmd' wrong: found $nums, expected $expected"
5788
5789         expected=4
5790         cmd="$LFS find -stripe-size 256k -type f $dir"
5791         nums=$($cmd | wc -l)
5792         [ $nums -eq $expected ] ||
5793                 error "'$cmd' wrong: found $nums, expected $expected"
5794
5795         cmd="$LFS find -stripe-size -320k -type f $dir"
5796         nums=$($cmd | wc -l)
5797         [ $nums -eq $expected ] ||
5798                 error "'$cmd' wrong: found $nums, expected $expected"
5799
5800         expected=0
5801         cmd="$LFS find -stripe-size 1024k -type f $dir"
5802         nums=$($cmd | wc -l)
5803         [ $nums -eq $expected ] ||
5804                 error "'$cmd' wrong: found $nums, expected $expected"
5805 }
5806 run_test 56t "check lfs find -stripe-size works"
5807
5808 test_56u() { # LU-611
5809         local dir=$DIR/$tdir
5810
5811         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5812
5813         if [[ $OSTCOUNT -gt 1 ]]; then
5814                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5815                 onestripe=4
5816         else
5817                 onestripe=0
5818         fi
5819
5820         local expected=$(((NUMDIRS + 1) * NUMFILES))
5821         local cmd="$LFS find -stripe-index 0 -type f $dir"
5822         local nums=$($cmd | wc -l)
5823
5824         [ $nums -eq $expected ] ||
5825                 error "'$cmd' wrong: found $nums, expected $expected"
5826
5827         expected=$onestripe
5828         cmd="$LFS find -stripe-index 1 -type f $dir"
5829         nums=$($cmd | wc -l)
5830         [ $nums -eq $expected ] ||
5831                 error "'$cmd' wrong: found $nums, expected $expected"
5832
5833         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5834         nums=$($cmd | wc -l)
5835         [ $nums -eq $expected ] ||
5836                 error "'$cmd' wrong: found $nums, expected $expected"
5837
5838         expected=0
5839         # This should produce an error and not return any files
5840         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5841         nums=$($cmd 2>/dev/null | wc -l)
5842         [ $nums -eq $expected ] ||
5843                 error "'$cmd' wrong: found $nums, expected $expected"
5844
5845         if [[ $OSTCOUNT -gt 1 ]]; then
5846                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5847                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5848                 nums=$($cmd | wc -l)
5849                 [ $nums -eq $expected ] ||
5850                         error "'$cmd' wrong: found $nums, expected $expected"
5851         fi
5852 }
5853 run_test 56u "check lfs find -stripe-index works"
5854
5855 test_56v() {
5856         local mdt_idx=0
5857         local dir=$DIR/$tdir
5858
5859         setup_56 $dir $NUMFILES $NUMDIRS
5860
5861         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5862         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5863
5864         for file in $($LFS find -m $UUID $dir); do
5865                 file_midx=$($LFS getstripe -m $file)
5866                 [ $file_midx -eq $mdt_idx ] ||
5867                         error "lfs find -m $UUID != getstripe -m $file_midx"
5868         done
5869 }
5870 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5871
5872 test_56w() {
5873         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5875
5876         local dir=$DIR/$tdir
5877
5878         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5879
5880         local stripe_size=$($LFS getstripe -S -d $dir) ||
5881                 error "$LFS getstripe -S -d $dir failed"
5882         stripe_size=${stripe_size%% *}
5883
5884         local file_size=$((stripe_size * OSTCOUNT))
5885         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5886         local required_space=$((file_num * file_size))
5887         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5888                            head -n1)
5889         [[ $free_space -le $((required_space / 1024)) ]] &&
5890                 skip_env "need $required_space, have $free_space kbytes"
5891
5892         local dd_bs=65536
5893         local dd_count=$((file_size / dd_bs))
5894
5895         # write data into the files
5896         local i
5897         local j
5898         local file
5899
5900         for i in $(seq $NUMFILES); do
5901                 file=$dir/file$i
5902                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5903                         error "write data into $file failed"
5904         done
5905         for i in $(seq $NUMDIRS); do
5906                 for j in $(seq $NUMFILES); do
5907                         file=$dir/dir$i/file$j
5908                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5909                                 error "write data into $file failed"
5910                 done
5911         done
5912
5913         # $LFS_MIGRATE will fail if hard link migration is unsupported
5914         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5915                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5916                         error "creating links to $dir/dir1/file1 failed"
5917         fi
5918
5919         local expected=-1
5920
5921         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5922
5923         # lfs_migrate file
5924         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5925
5926         echo "$cmd"
5927         eval $cmd || error "$cmd failed"
5928
5929         check_stripe_count $dir/file1 $expected
5930
5931         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5932         then
5933                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5934                 # OST 1 if it is on OST 0. This file is small enough to
5935                 # be on only one stripe.
5936                 file=$dir/migr_1_ost
5937                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5938                         error "write data into $file failed"
5939                 local obdidx=$($LFS getstripe -i $file)
5940                 local oldmd5=$(md5sum $file)
5941                 local newobdidx=0
5942
5943                 [[ $obdidx -eq 0 ]] && newobdidx=1
5944                 cmd="$LFS migrate -i $newobdidx $file"
5945                 echo $cmd
5946                 eval $cmd || error "$cmd failed"
5947
5948                 local realobdix=$($LFS getstripe -i $file)
5949                 local newmd5=$(md5sum $file)
5950
5951                 [[ $newobdidx -ne $realobdix ]] &&
5952                         error "new OST is different (was=$obdidx, "\
5953                               "wanted=$newobdidx, got=$realobdix)"
5954                 [[ "$oldmd5" != "$newmd5" ]] &&
5955                         error "md5sum differ: $oldmd5, $newmd5"
5956         fi
5957
5958         # lfs_migrate dir
5959         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5960         echo "$cmd"
5961         eval $cmd || error "$cmd failed"
5962
5963         for j in $(seq $NUMFILES); do
5964                 check_stripe_count $dir/dir1/file$j $expected
5965         done
5966
5967         # lfs_migrate works with lfs find
5968         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5969              $LFS_MIGRATE -y -c $expected"
5970         echo "$cmd"
5971         eval $cmd || error "$cmd failed"
5972
5973         for i in $(seq 2 $NUMFILES); do
5974                 check_stripe_count $dir/file$i $expected
5975         done
5976         for i in $(seq 2 $NUMDIRS); do
5977                 for j in $(seq $NUMFILES); do
5978                 check_stripe_count $dir/dir$i/file$j $expected
5979                 done
5980         done
5981 }
5982 run_test 56w "check lfs_migrate -c stripe_count works"
5983
5984 test_56wb() {
5985         local file1=$DIR/$tdir/file1
5986         local create_pool=false
5987         local initial_pool=$($LFS getstripe -p $DIR)
5988         local pool_list=()
5989         local pool=""
5990
5991         echo -n "Creating test dir..."
5992         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5993         echo "done."
5994
5995         echo -n "Creating test file..."
5996         touch $file1 || error "cannot create file"
5997         echo "done."
5998
5999         echo -n "Detecting existing pools..."
6000         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6001
6002         if [ ${#pool_list[@]} -gt 0 ]; then
6003                 echo "${pool_list[@]}"
6004                 for thispool in "${pool_list[@]}"; do
6005                         if [[ -z "$initial_pool" ||
6006                               "$initial_pool" != "$thispool" ]]; then
6007                                 pool="$thispool"
6008                                 echo "Using existing pool '$pool'"
6009                                 break
6010                         fi
6011                 done
6012         else
6013                 echo "none detected."
6014         fi
6015         if [ -z "$pool" ]; then
6016                 pool=${POOL:-testpool}
6017                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6018                 echo -n "Creating pool '$pool'..."
6019                 create_pool=true
6020                 pool_add $pool &> /dev/null ||
6021                         error "pool_add failed"
6022                 echo "done."
6023
6024                 echo -n "Adding target to pool..."
6025                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6026                         error "pool_add_targets failed"
6027                 echo "done."
6028         fi
6029
6030         echo -n "Setting pool using -p option..."
6031         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6032                 error "migrate failed rc = $?"
6033         echo "done."
6034
6035         echo -n "Verifying test file is in pool after migrating..."
6036         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6037                 error "file was not migrated to pool $pool"
6038         echo "done."
6039
6040         echo -n "Removing test file from pool '$pool'..."
6041         $LFS migrate $file1 &> /dev/null ||
6042                 error "cannot remove from pool"
6043         [ "$($LFS getstripe -p $file1)" ] &&
6044                 error "pool still set"
6045         echo "done."
6046
6047         echo -n "Setting pool using --pool option..."
6048         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6049                 error "migrate failed rc = $?"
6050         echo "done."
6051
6052         # Clean up
6053         rm -f $file1
6054         if $create_pool; then
6055                 destroy_test_pools 2> /dev/null ||
6056                         error "destroy test pools failed"
6057         fi
6058 }
6059 run_test 56wb "check lfs_migrate pool support"
6060
6061 test_56wc() {
6062         local file1="$DIR/$tdir/file1"
6063
6064         echo -n "Creating test dir..."
6065         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6066         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6067         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6068                 error "cannot set stripe"
6069         echo "done"
6070
6071         echo -n "Setting initial stripe for test file..."
6072         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6073                 error "cannot set stripe"
6074         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6075                 error "stripe size not set"
6076         echo "done."
6077
6078         # File currently set to -S 512K -c 1
6079
6080         # Ensure -c and -S options are rejected when -R is set
6081         echo -n "Verifying incompatible options are detected..."
6082         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6083                 error "incompatible -c and -R options not detected"
6084         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6085                 error "incompatible -S and -R options not detected"
6086         echo "done."
6087
6088         # Ensure unrecognized options are passed through to 'lfs migrate'
6089         echo -n "Verifying -S option is passed through to lfs migrate..."
6090         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6091                 error "migration failed"
6092         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6093                 error "file was not restriped"
6094         echo "done."
6095
6096         # File currently set to -S 1M -c 1
6097
6098         # Ensure long options are supported
6099         echo -n "Verifying long options supported..."
6100         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6101                 error "long option without argument not supported"
6102         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6103                 error "long option with argument not supported"
6104         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6105                 error "file not restriped with --stripe-size option"
6106         echo "done."
6107
6108         # File currently set to -S 512K -c 1
6109
6110         if [ "$OSTCOUNT" -gt 1 ]; then
6111                 echo -n "Verifying explicit stripe count can be set..."
6112                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6113                         error "migrate failed"
6114                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6115                         error "file not restriped to explicit count"
6116                 echo "done."
6117         fi
6118
6119         # File currently set to -S 512K -c 1 or -S 512K -c 2
6120
6121         # Ensure parent striping is used if -R is set, and no stripe
6122         # count or size is specified
6123         echo -n "Setting stripe for parent directory..."
6124         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6125                 error "cannot set stripe"
6126         echo "done."
6127
6128         echo -n "Verifying restripe option uses parent stripe settings..."
6129         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6130                 error "migrate failed"
6131         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6132                 error "file not restriped to parent settings"
6133         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6134                 error "file not restriped to parent settings"
6135         echo "done."
6136
6137         # File currently set to -S 1M -c 1
6138
6139         # Ensure striping is preserved if -R is not set, and no stripe
6140         # count or size is specified
6141         echo -n "Verifying striping size preserved when not specified..."
6142         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6143         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6144                 error "cannot set stripe on parent directory"
6145         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6146                 error "migrate failed"
6147         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6148                 error "file was restriped"
6149         echo "done."
6150
6151         # Ensure file name properly detected when final option has no argument
6152         echo -n "Verifying file name properly detected..."
6153         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6154                 error "file name interpreted as option argument"
6155         echo "done."
6156
6157         # Clean up
6158         rm -f "$file1"
6159 }
6160 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6161
6162 test_56wd() {
6163         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6164
6165         local file1=$DIR/$tdir/file1
6166
6167         echo -n "Creating test dir..."
6168         test_mkdir $DIR/$tdir || error "cannot create dir"
6169         echo "done."
6170
6171         echo -n "Creating test file..."
6172         touch $file1
6173         echo "done."
6174
6175         # Ensure 'lfs migrate' will fail by using a non-existent option,
6176         # and make sure rsync is not called to recover
6177         echo -n "Make sure --no-rsync option works..."
6178         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6179                 grep -q 'refusing to fall back to rsync' ||
6180                 error "rsync was called with --no-rsync set"
6181         echo "done."
6182
6183         # Ensure rsync is called without trying 'lfs migrate' first
6184         echo -n "Make sure --rsync option works..."
6185         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6186                 grep -q 'falling back to rsync' &&
6187                 error "lfs migrate was called with --rsync set"
6188         echo "done."
6189
6190         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6191         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6192                 grep -q 'at the same time' ||
6193                 error "--rsync and --no-rsync accepted concurrently"
6194         echo "done."
6195
6196         # Clean up
6197         rm -f $file1
6198 }
6199 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6200
6201 test_56x() {
6202         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6203         check_swap_layouts_support
6204
6205         local dir=$DIR/$tdir
6206         local ref1=/etc/passwd
6207         local file1=$dir/file1
6208
6209         test_mkdir $dir || error "creating dir $dir"
6210         $LFS setstripe -c 2 $file1
6211         cp $ref1 $file1
6212         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6213         stripe=$($LFS getstripe -c $file1)
6214         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6215         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6216
6217         # clean up
6218         rm -f $file1
6219 }
6220 run_test 56x "lfs migration support"
6221
6222 test_56xa() {
6223         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6224         check_swap_layouts_support
6225
6226         local dir=$DIR/$tdir/$testnum
6227
6228         test_mkdir -p $dir
6229
6230         local ref1=/etc/passwd
6231         local file1=$dir/file1
6232
6233         $LFS setstripe -c 2 $file1
6234         cp $ref1 $file1
6235         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6236
6237         local stripe=$($LFS getstripe -c $file1)
6238
6239         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6240         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6241
6242         # clean up
6243         rm -f $file1
6244 }
6245 run_test 56xa "lfs migration --block support"
6246
6247 check_migrate_links() {
6248         local dir="$1"
6249         local file1="$dir/file1"
6250         local begin="$2"
6251         local count="$3"
6252         local total_count=$(($begin + $count - 1))
6253         local symlink_count=10
6254         local uniq_count=10
6255
6256         if [ ! -f "$file1" ]; then
6257                 echo -n "creating initial file..."
6258                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6259                         error "cannot setstripe initial file"
6260                 echo "done"
6261
6262                 echo -n "creating symlinks..."
6263                 for s in $(seq 1 $symlink_count); do
6264                         ln -s "$file1" "$dir/slink$s" ||
6265                                 error "cannot create symlinks"
6266                 done
6267                 echo "done"
6268
6269                 echo -n "creating nonlinked files..."
6270                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6271                         error "cannot create nonlinked files"
6272                 echo "done"
6273         fi
6274
6275         # create hard links
6276         if [ ! -f "$dir/file$total_count" ]; then
6277                 echo -n "creating hard links $begin:$total_count..."
6278                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6279                         /dev/null || error "cannot create hard links"
6280                 echo "done"
6281         fi
6282
6283         echo -n "checking number of hard links listed in xattrs..."
6284         local fid=$($LFS getstripe -F "$file1")
6285         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6286
6287         echo "${#paths[*]}"
6288         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6289                         skip "hard link list has unexpected size, skipping test"
6290         fi
6291         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6292                         error "link names should exceed xattrs size"
6293         fi
6294
6295         echo -n "migrating files..."
6296         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
6297         local rc=$?
6298         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6299         echo "done"
6300
6301         # make sure all links have been properly migrated
6302         echo -n "verifying files..."
6303         fid=$($LFS getstripe -F "$file1") ||
6304                 error "cannot get fid for file $file1"
6305         for i in $(seq 2 $total_count); do
6306                 local fid2=$($LFS getstripe -F $dir/file$i)
6307
6308                 [ "$fid2" == "$fid" ] ||
6309                         error "migrated hard link has mismatched FID"
6310         done
6311
6312         # make sure hard links were properly detected, and migration was
6313         # performed only once for the entire link set; nonlinked files should
6314         # also be migrated
6315         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
6316         local expected=$(($uniq_count + 1))
6317
6318         [ "$actual" -eq  "$expected" ] ||
6319                 error "hard links individually migrated ($actual != $expected)"
6320
6321         # make sure the correct number of hard links are present
6322         local hardlinks=$(stat -c '%h' "$file1")
6323
6324         [ $hardlinks -eq $total_count ] ||
6325                 error "num hard links $hardlinks != $total_count"
6326         echo "done"
6327
6328         return 0
6329 }
6330
6331 test_56xb() {
6332         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6333                 skip "Need MDS version at least 2.10.55"
6334
6335         local dir="$DIR/$tdir"
6336
6337         test_mkdir "$dir" || error "cannot create dir $dir"
6338
6339         echo "testing lfs migrate mode when all links fit within xattrs"
6340         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6341
6342         echo "testing rsync mode when all links fit within xattrs"
6343         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6344
6345         echo "testing lfs migrate mode when all links do not fit within xattrs"
6346         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6347
6348         echo "testing rsync mode when all links do not fit within xattrs"
6349         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6350
6351
6352         # clean up
6353         rm -rf $dir
6354 }
6355 run_test 56xb "lfs migration hard link support"
6356
6357 test_56xc() {
6358         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6359
6360         local dir="$DIR/$tdir"
6361
6362         test_mkdir "$dir" || error "cannot create dir $dir"
6363
6364         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6365         echo -n "Setting initial stripe for 20MB test file..."
6366         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
6367         echo "done"
6368         echo -n "Sizing 20MB test file..."
6369         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6370         echo "done"
6371         echo -n "Verifying small file autostripe count is 1..."
6372         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
6373                 error "cannot migrate 20MB file"
6374         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6375                 error "cannot get stripe for $dir/20mb"
6376         [ $stripe_count -eq 1 ] ||
6377                 error "unexpected stripe count $stripe_count for 20MB file"
6378         rm -f "$dir/20mb"
6379         echo "done"
6380
6381         # Test 2: File is small enough to fit within the available space on
6382         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6383         # have at least an additional 1KB for each desired stripe for test 3
6384         echo -n "Setting stripe for 1GB test file..."
6385         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
6386         echo "done"
6387         echo -n "Sizing 1GB test file..."
6388         # File size is 1GB + 3KB
6389         truncate "$dir/1gb" 1073744896 &> /dev/null ||
6390                 error "cannot create 1GB test file"
6391         echo "done"
6392         echo -n "Migrating 1GB file..."
6393         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
6394                 error "cannot migrate file"
6395         echo "done"
6396         echo -n "Verifying autostripe count is sqrt(n) + 1..."
6397         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6398                 error "cannot get stripe for $dir/1gb"
6399         [ $stripe_count -eq 2 ] ||
6400                 error "unexpected stripe count $stripe_count (expected 2)"
6401         echo "done"
6402
6403         # Test 3: File is too large to fit within the available space on
6404         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6405         if [ $OSTCOUNT -ge 3 ]; then
6406                 # The required available space is calculated as
6407                 # file size (1GB + 3KB) / OST count (3).
6408                 local kb_per_ost=349526
6409
6410                 echo -n "Migrating 1GB file..."
6411                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
6412                         /dev/null || error "cannot migrate file"
6413                 echo "done"
6414
6415                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6416                 echo -n "Verifying autostripe count with limited space..."
6417                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
6418                         error "unexpected stripe count $stripe_count (wanted 3)"
6419                 echo "done"
6420         fi
6421
6422         # clean up
6423         rm -rf $dir
6424 }
6425 run_test 56xc "lfs migration autostripe"
6426
6427 test_56y() {
6428         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6429                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6430
6431         local res=""
6432         local dir=$DIR/$tdir
6433         local f1=$dir/file1
6434         local f2=$dir/file2
6435
6436         test_mkdir -p $dir || error "creating dir $dir"
6437         touch $f1 || error "creating std file $f1"
6438         $MULTIOP $f2 H2c || error "creating released file $f2"
6439
6440         # a directory can be raid0, so ask only for files
6441         res=$($LFS find $dir -L raid0 -type f | wc -l)
6442         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6443
6444         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6445         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6446
6447         # only files can be released, so no need to force file search
6448         res=$($LFS find $dir -L released)
6449         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6450
6451         res=$($LFS find $dir -type f \! -L released)
6452         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6453 }
6454 run_test 56y "lfs find -L raid0|released"
6455
6456 test_56z() { # LU-4824
6457         # This checks to make sure 'lfs find' continues after errors
6458         # There are two classes of errors that should be caught:
6459         # - If multiple paths are provided, all should be searched even if one
6460         #   errors out
6461         # - If errors are encountered during the search, it should not terminate
6462         #   early
6463         local dir=$DIR/$tdir
6464         local i
6465
6466         test_mkdir $dir
6467         for i in d{0..9}; do
6468                 test_mkdir $dir/$i
6469         done
6470         touch $dir/d{0..9}/$tfile
6471         $LFS find $DIR/non_existent_dir $dir &&
6472                 error "$LFS find did not return an error"
6473         # Make a directory unsearchable. This should NOT be the last entry in
6474         # directory order.  Arbitrarily pick the 6th entry
6475         chmod 700 $($LFS find $dir -type d | sed '6!d')
6476
6477         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6478
6479         # The user should be able to see 10 directories and 9 files
6480         [ $count == 19 ] || error "$LFS find did not continue after error"
6481 }
6482 run_test 56z "lfs find should continue after an error"
6483
6484 test_56aa() { # LU-5937
6485         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6486
6487         local dir=$DIR/$tdir
6488
6489         mkdir $dir
6490         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6491
6492         createmany -o $dir/striped_dir/${tfile}- 1024
6493         local dirs=$($LFS find --size +8k $dir/)
6494
6495         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6496 }
6497 run_test 56aa "lfs find --size under striped dir"
6498
6499 test_56ab() { # LU-10705
6500         test_mkdir $DIR/$tdir
6501         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6502         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6503         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6504         # Flush writes to ensure valid blocks.  Need to be more thorough for
6505         # ZFS, since blocks are not allocated/returned to client immediately.
6506         sync_all_data
6507         wait_zfs_commit ost1 2
6508         cancel_lru_locks osc
6509         ls -ls $DIR/$tdir
6510
6511         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6512
6513         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6514
6515         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6516         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6517
6518         rm -f $DIR/$tdir/$tfile.[123]
6519 }
6520 run_test 56ab "lfs find --blocks"
6521
6522 test_56ba() {
6523         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6524                 skip "Need MDS version at least 2.10.50"
6525
6526         # Create composite files with one component
6527         local dir=$DIR/$tdir
6528
6529         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6530         # Create composite files with three components
6531         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6532         # Create non-composite files
6533         createmany -o $dir/${tfile}- 10
6534
6535         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6536
6537         [[ $nfiles == 10 ]] ||
6538                 error "lfs find -E 1M found $nfiles != 10 files"
6539
6540         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6541         [[ $nfiles == 25 ]] ||
6542                 error "lfs find ! -E 1M found $nfiles != 25 files"
6543
6544         # All files have a component that starts at 0
6545         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6546         [[ $nfiles == 35 ]] ||
6547                 error "lfs find --component-start 0 - $nfiles != 35 files"
6548
6549         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6550         [[ $nfiles == 15 ]] ||
6551                 error "lfs find --component-start 2M - $nfiles != 15 files"
6552
6553         # All files created here have a componenet that does not starts at 2M
6554         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6555         [[ $nfiles == 35 ]] ||
6556                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6557
6558         # Find files with a specified number of components
6559         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6560         [[ $nfiles == 15 ]] ||
6561                 error "lfs find --component-count 3 - $nfiles != 15 files"
6562
6563         # Remember non-composite files have a component count of zero
6564         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6565         [[ $nfiles == 10 ]] ||
6566                 error "lfs find --component-count 0 - $nfiles != 10 files"
6567
6568         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6569         [[ $nfiles == 20 ]] ||
6570                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6571
6572         # All files have a flag called "init"
6573         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6574         [[ $nfiles == 35 ]] ||
6575                 error "lfs find --component-flags init - $nfiles != 35 files"
6576
6577         # Multi-component files will have a component not initialized
6578         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6579         [[ $nfiles == 15 ]] ||
6580                 error "lfs find !--component-flags init - $nfiles != 15 files"
6581
6582         rm -rf $dir
6583
6584 }
6585 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6586
6587 test_56ca() {
6588         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6589                 skip "Need MDS version at least 2.10.57"
6590
6591         local td=$DIR/$tdir
6592         local tf=$td/$tfile
6593         local dir
6594         local nfiles
6595         local cmd
6596         local i
6597         local j
6598
6599         # create mirrored directories and mirrored files
6600         mkdir $td || error "mkdir $td failed"
6601         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6602         createmany -o $tf- 10 || error "create $tf- failed"
6603
6604         for i in $(seq 2); do
6605                 dir=$td/dir$i
6606                 mkdir $dir || error "mkdir $dir failed"
6607                 $LFS mirror create -N$((3 + i)) $dir ||
6608                         error "create mirrored dir $dir failed"
6609                 createmany -o $dir/$tfile- 10 ||
6610                         error "create $dir/$tfile- failed"
6611         done
6612
6613         # change the states of some mirrored files
6614         echo foo > $tf-6
6615         for i in $(seq 2); do
6616                 dir=$td/dir$i
6617                 for j in $(seq 4 9); do
6618                         echo foo > $dir/$tfile-$j
6619                 done
6620         done
6621
6622         # find mirrored files with specific mirror count
6623         cmd="$LFS find --mirror-count 3 --type f $td"
6624         nfiles=$($cmd | wc -l)
6625         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6626
6627         cmd="$LFS find ! --mirror-count 3 --type f $td"
6628         nfiles=$($cmd | wc -l)
6629         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6630
6631         cmd="$LFS find --mirror-count +2 --type f $td"
6632         nfiles=$($cmd | wc -l)
6633         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6634
6635         cmd="$LFS find --mirror-count -6 --type f $td"
6636         nfiles=$($cmd | wc -l)
6637         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6638
6639         # find mirrored files with specific file state
6640         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6641         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6642
6643         cmd="$LFS find --mirror-state=ro --type f $td"
6644         nfiles=$($cmd | wc -l)
6645         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6646
6647         cmd="$LFS find ! --mirror-state=ro --type f $td"
6648         nfiles=$($cmd | wc -l)
6649         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6650
6651         cmd="$LFS find --mirror-state=wp --type f $td"
6652         nfiles=$($cmd | wc -l)
6653         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6654
6655         cmd="$LFS find ! --mirror-state=sp --type f $td"
6656         nfiles=$($cmd | wc -l)
6657         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6658 }
6659 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6660
6661 test_57a() {
6662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6663         # note test will not do anything if MDS is not local
6664         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6665                 skip_env "ldiskfs only test"
6666         fi
6667         remote_mds_nodsh && skip "remote MDS with nodsh"
6668
6669         local MNTDEV="osd*.*MDT*.mntdev"
6670         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6671         [ -z "$DEV" ] && error "can't access $MNTDEV"
6672         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6673                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6674                         error "can't access $DEV"
6675                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6676                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6677                 rm $TMP/t57a.dump
6678         done
6679 }
6680 run_test 57a "verify MDS filesystem created with large inodes =="
6681
6682 test_57b() {
6683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6684         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6685                 skip_env "ldiskfs only test"
6686         fi
6687         remote_mds_nodsh && skip "remote MDS with nodsh"
6688
6689         local dir=$DIR/$tdir
6690         local filecount=100
6691         local file1=$dir/f1
6692         local fileN=$dir/f$filecount
6693
6694         rm -rf $dir || error "removing $dir"
6695         test_mkdir -c1 $dir
6696         local mdtidx=$($LFS getstripe -m $dir)
6697         local mdtname=MDT$(printf %04x $mdtidx)
6698         local facet=mds$((mdtidx + 1))
6699
6700         echo "mcreating $filecount files"
6701         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6702
6703         # verify that files do not have EAs yet
6704         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6705                 error "$file1 has an EA"
6706         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6707                 error "$fileN has an EA"
6708
6709         sync
6710         sleep 1
6711         df $dir  #make sure we get new statfs data
6712         local mdsfree=$(do_facet $facet \
6713                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6714         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6715         local file
6716
6717         echo "opening files to create objects/EAs"
6718         for file in $(seq -f $dir/f%g 1 $filecount); do
6719                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6720                         error "opening $file"
6721         done
6722
6723         # verify that files have EAs now
6724         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6725         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6726
6727         sleep 1  #make sure we get new statfs data
6728         df $dir
6729         local mdsfree2=$(do_facet $facet \
6730                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6731         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6732
6733         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6734                 if [ "$mdsfree" != "$mdsfree2" ]; then
6735                         error "MDC before $mdcfree != after $mdcfree2"
6736                 else
6737                         echo "MDC before $mdcfree != after $mdcfree2"
6738                         echo "unable to confirm if MDS has large inodes"
6739                 fi
6740         fi
6741         rm -rf $dir
6742 }
6743 run_test 57b "default LOV EAs are stored inside large inodes ==="
6744
6745 test_58() {
6746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6747         [ -z "$(which wiretest 2>/dev/null)" ] &&
6748                         skip_env "could not find wiretest"
6749
6750         wiretest
6751 }
6752 run_test 58 "verify cross-platform wire constants =============="
6753
6754 test_59() {
6755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6756
6757         echo "touch 130 files"
6758         createmany -o $DIR/f59- 130
6759         echo "rm 130 files"
6760         unlinkmany $DIR/f59- 130
6761         sync
6762         # wait for commitment of removal
6763         wait_delete_completed
6764 }
6765 run_test 59 "verify cancellation of llog records async ========="
6766
6767 TEST60_HEAD="test_60 run $RANDOM"
6768 test_60a() {
6769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6770         remote_mgs_nodsh && skip "remote MGS with nodsh"
6771         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6772                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6773                         skip_env "missing subtest run-llog.sh"
6774
6775         log "$TEST60_HEAD - from kernel mode"
6776         do_facet mgs "$LCTL dk > /dev/null"
6777         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6778         do_facet mgs $LCTL dk > $TMP/$tfile
6779
6780         # LU-6388: test llog_reader
6781         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6782         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6783         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6784                         skip_env "missing llog_reader"
6785         local fstype=$(facet_fstype mgs)
6786         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6787                 skip_env "Only for ldiskfs or zfs type mgs"
6788
6789         local mntpt=$(facet_mntpt mgs)
6790         local mgsdev=$(mgsdevname 1)
6791         local fid_list
6792         local fid
6793         local rec_list
6794         local rec
6795         local rec_type
6796         local obj_file
6797         local path
6798         local seq
6799         local oid
6800         local pass=true
6801
6802         #get fid and record list
6803         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6804                 tail -n 4))
6805         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6806                 tail -n 4))
6807         #remount mgs as ldiskfs or zfs type
6808         stop mgs || error "stop mgs failed"
6809         mount_fstype mgs || error "remount mgs failed"
6810         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6811                 fid=${fid_list[i]}
6812                 rec=${rec_list[i]}
6813                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6814                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6815                 oid=$((16#$oid))
6816
6817                 case $fstype in
6818                         ldiskfs )
6819                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6820                         zfs )
6821                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6822                 esac
6823                 echo "obj_file is $obj_file"
6824                 do_facet mgs $llog_reader $obj_file
6825
6826                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6827                         awk '{ print $3 }' | sed -e "s/^type=//g")
6828                 if [ $rec_type != $rec ]; then
6829                         echo "FAILED test_60a wrong record type $rec_type," \
6830                               "should be $rec"
6831                         pass=false
6832                         break
6833                 fi
6834
6835                 #check obj path if record type is LLOG_LOGID_MAGIC
6836                 if [ "$rec" == "1064553b" ]; then
6837                         path=$(do_facet mgs $llog_reader $obj_file |
6838                                 grep "path=" | awk '{ print $NF }' |
6839                                 sed -e "s/^path=//g")
6840                         if [ $obj_file != $mntpt/$path ]; then
6841                                 echo "FAILED test_60a wrong obj path" \
6842                                       "$montpt/$path, should be $obj_file"
6843                                 pass=false
6844                                 break
6845                         fi
6846                 fi
6847         done
6848         rm -f $TMP/$tfile
6849         #restart mgs before "error", otherwise it will block the next test
6850         stop mgs || error "stop mgs failed"
6851         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6852         $pass || error "test failed, see FAILED test_60a messages for specifics"
6853 }
6854 run_test 60a "llog_test run from kernel module and test llog_reader"
6855
6856 test_60b() { # bug 6411
6857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6858
6859         dmesg > $DIR/$tfile
6860         LLOG_COUNT=$(do_facet mgs dmesg |
6861                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6862                           /llog_[a-z]*.c:[0-9]/ {
6863                                 if (marker)
6864                                         from_marker++
6865                                 from_begin++
6866                           }
6867                           END {
6868                                 if (marker)
6869                                         print from_marker
6870                                 else
6871                                         print from_begin
6872                           }")
6873
6874         [[ $LLOG_COUNT -gt 120 ]] &&
6875                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6876 }
6877 run_test 60b "limit repeated messages from CERROR/CWARN"
6878
6879 test_60c() {
6880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6881
6882         echo "create 5000 files"
6883         createmany -o $DIR/f60c- 5000
6884 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6885         lctl set_param fail_loc=0x80000137
6886         unlinkmany $DIR/f60c- 5000
6887         lctl set_param fail_loc=0
6888 }
6889 run_test 60c "unlink file when mds full"
6890
6891 test_60d() {
6892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6893
6894         SAVEPRINTK=$(lctl get_param -n printk)
6895         # verify "lctl mark" is even working"
6896         MESSAGE="test message ID $RANDOM $$"
6897         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6898         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6899
6900         lctl set_param printk=0 || error "set lnet.printk failed"
6901         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6902         MESSAGE="new test message ID $RANDOM $$"
6903         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6904         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6905         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6906
6907         lctl set_param -n printk="$SAVEPRINTK"
6908 }
6909 run_test 60d "test printk console message masking"
6910
6911 test_60e() {
6912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6913         remote_mds_nodsh && skip "remote MDS with nodsh"
6914
6915         touch $DIR/$tfile
6916 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6917         do_facet mds1 lctl set_param fail_loc=0x15b
6918         rm $DIR/$tfile
6919 }
6920 run_test 60e "no space while new llog is being created"
6921
6922 test_60g() {
6923         local pid
6924
6925         test_mkdir -c $MDSCOUNT $DIR/$tdir
6926         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6927
6928         (
6929                 local index=0
6930                 while true; do
6931                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6932                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6933                         index=$((index + 1))
6934                 done
6935         ) &
6936
6937         pid=$!
6938
6939         for i in $(seq 100); do 
6940                 # define OBD_FAIL_OSD_TXN_START    0x19a
6941                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6942                 usleep 100
6943         done
6944
6945         kill -9 $pid
6946
6947         mkdir $DIR/$tdir/new || error "mkdir failed"
6948         rmdir $DIR/$tdir/new || error "rmdir failed"
6949 }
6950 run_test 60g "transaction abort won't cause MDT hung"
6951
6952 test_60h() {
6953         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
6954                 skip "Need MDS version at least 2.12.52"
6955         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
6956
6957         local f
6958
6959         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
6960         #define OBD_FAIL_MDS_STRIPE_FID          0x189
6961         for fail_loc in 0x80000188 0x80000189; do
6962                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
6963                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
6964                         error "mkdir $dir-$fail_loc failed"
6965                 for i in {0..10}; do
6966                         # create may fail on missing stripe
6967                         echo $i > $DIR/$tdir-$fail_loc/$i
6968                 done
6969                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6970                         error "getdirstripe $tdir-$fail_loc failed"
6971                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
6972                         error "migrate $tdir-$fail_loc failed"
6973                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6974                         error "getdirstripe $tdir-$fail_loc failed"
6975                 pushd $DIR/$tdir-$fail_loc
6976                 for f in *; do
6977                         echo $f | cmp $f - || error "$f data mismatch"
6978                 done
6979                 popd
6980                 rm -rf $DIR/$tdir-$fail_loc
6981         done
6982 }
6983 run_test 60h "striped directory with missing stripes can be accessed"
6984
6985 test_61a() {
6986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6987
6988         f="$DIR/f61"
6989         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6990         cancel_lru_locks osc
6991         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6992         sync
6993 }
6994 run_test 61a "mmap() writes don't make sync hang ================"
6995
6996 test_61b() {
6997         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
6998 }
6999 run_test 61b "mmap() of unstriped file is successful"
7000
7001 # bug 2330 - insufficient obd_match error checking causes LBUG
7002 test_62() {
7003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7004
7005         f="$DIR/f62"
7006         echo foo > $f
7007         cancel_lru_locks osc
7008         lctl set_param fail_loc=0x405
7009         cat $f && error "cat succeeded, expect -EIO"
7010         lctl set_param fail_loc=0
7011 }
7012 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7013 # match every page all of the time.
7014 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7015
7016 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7017 # Though this test is irrelevant anymore, it helped to reveal some
7018 # other grant bugs (LU-4482), let's keep it.
7019 test_63a() {   # was test_63
7020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7021
7022         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7023
7024         for i in `seq 10` ; do
7025                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7026                 sleep 5
7027                 kill $!
7028                 sleep 1
7029         done
7030
7031         rm -f $DIR/f63 || true
7032 }
7033 run_test 63a "Verify oig_wait interruption does not crash ======="
7034
7035 # bug 2248 - async write errors didn't return to application on sync
7036 # bug 3677 - async write errors left page locked
7037 test_63b() {
7038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7039
7040         debugsave
7041         lctl set_param debug=-1
7042
7043         # ensure we have a grant to do async writes
7044         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7045         rm $DIR/$tfile
7046
7047         sync    # sync lest earlier test intercept the fail_loc
7048
7049         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7050         lctl set_param fail_loc=0x80000406
7051         $MULTIOP $DIR/$tfile Owy && \
7052                 error "sync didn't return ENOMEM"
7053         sync; sleep 2; sync     # do a real sync this time to flush page
7054         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7055                 error "locked page left in cache after async error" || true
7056         debugrestore
7057 }
7058 run_test 63b "async write errors should be returned to fsync ==="
7059
7060 test_64a () {
7061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7062
7063         df $DIR
7064         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7065 }
7066 run_test 64a "verify filter grant calculations (in kernel) ====="
7067
7068 test_64b () {
7069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7070
7071         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7072 }
7073 run_test 64b "check out-of-space detection on client"
7074
7075 test_64c() {
7076         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7077 }
7078 run_test 64c "verify grant shrink"
7079
7080 # this does exactly what osc_request.c:osc_announce_cached() does in
7081 # order to calculate max amount of grants to ask from server
7082 want_grant() {
7083         local tgt=$1
7084
7085         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7086         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7087
7088         ((rpc_in_flight ++));
7089         nrpages=$((nrpages * rpc_in_flight))
7090
7091         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7092
7093         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7094
7095         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7096         local undirty=$((nrpages * PAGE_SIZE))
7097
7098         local max_extent_pages
7099         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7100             grep grant_max_extent_size | awk '{print $2}')
7101         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7102         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7103         local grant_extent_tax
7104         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7105             grep grant_extent_tax | awk '{print $2}')
7106
7107         undirty=$((undirty + nrextents * grant_extent_tax))
7108
7109         echo $undirty
7110 }
7111
7112 # this is size of unit for grant allocation. It should be equal to
7113 # what tgt_grant.c:tgt_grant_chunk() calculates
7114 grant_chunk() {
7115         local tgt=$1
7116         local max_brw_size
7117         local grant_extent_tax
7118
7119         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7120             grep max_brw_size | awk '{print $2}')
7121
7122         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7123             grep grant_extent_tax | awk '{print $2}')
7124
7125         echo $(((max_brw_size + grant_extent_tax) * 2))
7126 }
7127
7128 test_64d() {
7129         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7130                 skip "OST < 2.10.55 doesn't limit grants enough"
7131
7132         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7133         local file=$DIR/$tfile
7134
7135         [[ $($LCTL get_param osc.${tgt}.import |
7136              grep "connect_flags:.*grant_param") ]] ||
7137                 skip "no grant_param connect flag"
7138
7139         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7140
7141         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7142
7143         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7144         stack_trap "rm -f $file" EXIT
7145
7146         $LFS setstripe $file -i 0 -c 1
7147         dd if=/dev/zero of=$file bs=1M count=1000 &
7148         ddpid=$!
7149
7150         while true
7151         do
7152                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7153                 if [[ $cur_grant -gt $max_cur_granted ]]
7154                 then
7155                         kill $ddpid
7156                         error "cur_grant $cur_grant > $max_cur_granted"
7157                 fi
7158                 kill -0 $ddpid
7159                 [[ $? -ne 0 ]] && break;
7160                 sleep 2
7161         done
7162
7163         rm -f $DIR/$tfile
7164         wait_delete_completed
7165         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7166 }
7167 run_test 64d "check grant limit exceed"
7168
7169 # bug 1414 - set/get directories' stripe info
7170 test_65a() {
7171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7172
7173         test_mkdir $DIR/$tdir
7174         touch $DIR/$tdir/f1
7175         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7176 }
7177 run_test 65a "directory with no stripe info"
7178
7179 test_65b() {
7180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7181
7182         test_mkdir $DIR/$tdir
7183         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7184
7185         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7186                                                 error "setstripe"
7187         touch $DIR/$tdir/f2
7188         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7189 }
7190 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7191
7192 test_65c() {
7193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7194         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7195
7196         test_mkdir $DIR/$tdir
7197         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7198
7199         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7200                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7201         touch $DIR/$tdir/f3
7202         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7203 }
7204 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7205
7206 test_65d() {
7207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7208
7209         test_mkdir $DIR/$tdir
7210         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7211         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7212
7213         if [[ $STRIPECOUNT -le 0 ]]; then
7214                 sc=1
7215         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7216                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7217                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7218         else
7219                 sc=$(($STRIPECOUNT - 1))
7220         fi
7221         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7222         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7223         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7224                 error "lverify failed"
7225 }
7226 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7227
7228 test_65e() {
7229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7230
7231         test_mkdir $DIR/$tdir
7232
7233         $LFS setstripe $DIR/$tdir || error "setstripe"
7234         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7235                                         error "no stripe info failed"
7236         touch $DIR/$tdir/f6
7237         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7238 }
7239 run_test 65e "directory setstripe defaults"
7240
7241 test_65f() {
7242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7243
7244         test_mkdir $DIR/${tdir}f
7245         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7246                 error "setstripe succeeded" || true
7247 }
7248 run_test 65f "dir setstripe permission (should return error) ==="
7249
7250 test_65g() {
7251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7252
7253         test_mkdir $DIR/$tdir
7254         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7255
7256         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7257                 error "setstripe -S failed"
7258         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7259         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7260                 error "delete default stripe failed"
7261 }
7262 run_test 65g "directory setstripe -d"
7263
7264 test_65h() {
7265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7266
7267         test_mkdir $DIR/$tdir
7268         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7269
7270         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7271                 error "setstripe -S failed"
7272         test_mkdir $DIR/$tdir/dd1
7273         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7274                 error "stripe info inherit failed"
7275 }
7276 run_test 65h "directory stripe info inherit ===================="
7277
7278 test_65i() {
7279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7280
7281         save_layout_restore_at_exit $MOUNT
7282
7283         # bug6367: set non-default striping on root directory
7284         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7285
7286         # bug12836: getstripe on -1 default directory striping
7287         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7288
7289         # bug12836: getstripe -v on -1 default directory striping
7290         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7291
7292         # bug12836: new find on -1 default directory striping
7293         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7294 }
7295 run_test 65i "various tests to set root directory striping"
7296
7297 test_65j() { # bug6367
7298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7299
7300         sync; sleep 1
7301
7302         # if we aren't already remounting for each test, do so for this test
7303         if [ "$I_MOUNTED" = "yes" ]; then
7304                 cleanup || error "failed to unmount"
7305                 setup
7306         fi
7307
7308         save_layout_restore_at_exit $MOUNT
7309
7310         $LFS setstripe -d $MOUNT || error "setstripe failed"
7311 }
7312 run_test 65j "set default striping on root directory (bug 6367)="
7313
7314 cleanup_65k() {
7315         rm -rf $DIR/$tdir
7316         wait_delete_completed
7317         do_facet $SINGLEMDS "lctl set_param -n \
7318                 osp.$ost*MDT0000.max_create_count=$max_count"
7319         do_facet $SINGLEMDS "lctl set_param -n \
7320                 osp.$ost*MDT0000.create_count=$count"
7321         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7322         echo $INACTIVE_OSC "is Activate"
7323
7324         wait_osc_import_state mds ost$ostnum FULL
7325 }
7326
7327 test_65k() { # bug11679
7328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7329         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7330         remote_mds_nodsh && skip "remote MDS with nodsh"
7331
7332         local disable_precreate=true
7333         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7334                 disable_precreate=false
7335
7336         echo "Check OST status: "
7337         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7338                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7339
7340         for OSC in $MDS_OSCS; do
7341                 echo $OSC "is active"
7342                 do_facet $SINGLEMDS lctl --device %$OSC activate
7343         done
7344
7345         for INACTIVE_OSC in $MDS_OSCS; do
7346                 local ost=$(osc_to_ost $INACTIVE_OSC)
7347                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7348                                lov.*md*.target_obd |
7349                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7350
7351                 mkdir -p $DIR/$tdir
7352                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7353                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7354
7355                 echo "Deactivate: " $INACTIVE_OSC
7356                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7357
7358                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7359                               osp.$ost*MDT0000.create_count")
7360                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7361                                   osp.$ost*MDT0000.max_create_count")
7362                 $disable_precreate &&
7363                         do_facet $SINGLEMDS "lctl set_param -n \
7364                                 osp.$ost*MDT0000.max_create_count=0"
7365
7366                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7367                         [ -f $DIR/$tdir/$idx ] && continue
7368                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7369                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7370                                 { cleanup_65k;
7371                                   error "setstripe $idx should succeed"; }
7372                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7373                 done
7374                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7375                 rmdir $DIR/$tdir
7376
7377                 do_facet $SINGLEMDS "lctl set_param -n \
7378                         osp.$ost*MDT0000.max_create_count=$max_count"
7379                 do_facet $SINGLEMDS "lctl set_param -n \
7380                         osp.$ost*MDT0000.create_count=$count"
7381                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7382                 echo $INACTIVE_OSC "is Activate"
7383
7384                 wait_osc_import_state mds ost$ostnum FULL
7385         done
7386 }
7387 run_test 65k "validate manual striping works properly with deactivated OSCs"
7388
7389 test_65l() { # bug 12836
7390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7391
7392         test_mkdir -p $DIR/$tdir/test_dir
7393         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7394         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7395 }
7396 run_test 65l "lfs find on -1 stripe dir ========================"
7397
7398 test_65m() {
7399         local layout=$(save_layout $MOUNT)
7400         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7401                 restore_layout $MOUNT $layout
7402                 error "setstripe should fail by non-root users"
7403         }
7404         true
7405 }
7406 run_test 65m "normal user can't set filesystem default stripe"
7407
7408 test_65n() {
7409         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7410         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7411                 skip "Need MDS version at least 2.12.50"
7412         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7413
7414         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7415         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7416         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7417
7418         local root_layout=$(save_layout $MOUNT)
7419         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7420
7421         # new subdirectory under root directory should not inherit
7422         # the default layout from root
7423         local dir1=$MOUNT/$tdir-1
7424         mkdir $dir1 || error "mkdir $dir1 failed"
7425         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7426                 error "$dir1 shouldn't have LOV EA"
7427
7428         # delete the default layout on root directory
7429         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7430
7431         local dir2=$MOUNT/$tdir-2
7432         mkdir $dir2 || error "mkdir $dir2 failed"
7433         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7434                 error "$dir2 shouldn't have LOV EA"
7435
7436         # set a new striping pattern on root directory
7437         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7438         local new_def_stripe_size=$((def_stripe_size * 2))
7439         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7440                 error "set stripe size on $MOUNT failed"
7441
7442         # new file created in $dir2 should inherit the new stripe size from
7443         # the filesystem default
7444         local file2=$dir2/$tfile-2
7445         touch $file2 || error "touch $file2 failed"
7446
7447         local file2_stripe_size=$($LFS getstripe -S $file2)
7448         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7449                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7450
7451         local dir3=$MOUNT/$tdir-3
7452         mkdir $dir3 || error "mkdir $dir3 failed"
7453         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7454                 error "$dir3 shouldn't have LOV EA"
7455
7456         # set OST pool on root directory
7457         local pool=$TESTNAME
7458         pool_add $pool || error "add $pool failed"
7459         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7460                 error "add targets to $pool failed"
7461
7462         $LFS setstripe -p $pool $MOUNT ||
7463                 error "set OST pool on $MOUNT failed"
7464
7465         # new file created in $dir3 should inherit the pool from
7466         # the filesystem default
7467         local file3=$dir3/$tfile-3
7468         touch $file3 || error "touch $file3 failed"
7469
7470         local file3_pool=$($LFS getstripe -p $file3)
7471         [[ "$file3_pool" = "$pool" ]] ||
7472                 error "$file3 didn't inherit OST pool $pool"
7473
7474         local dir4=$MOUNT/$tdir-4
7475         mkdir $dir4 || error "mkdir $dir4 failed"
7476         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7477                 error "$dir4 shouldn't have LOV EA"
7478
7479         # new file created in $dir4 should inherit the pool from
7480         # the filesystem default
7481         local file4=$dir4/$tfile-4
7482         touch $file4 || error "touch $file4 failed"
7483
7484         local file4_pool=$($LFS getstripe -p $file4)
7485         [[ "$file4_pool" = "$pool" ]] ||
7486                 error "$file4 didn't inherit OST pool $pool"
7487
7488         # new subdirectory under non-root directory should inherit
7489         # the default layout from its parent directory
7490         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7491                 error "set directory layout on $dir4 failed"
7492
7493         local dir5=$dir4/$tdir-5
7494         mkdir $dir5 || error "mkdir $dir5 failed"
7495
7496         local dir4_layout=$(get_layout_param $dir4)
7497         local dir5_layout=$(get_layout_param $dir5)
7498         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7499                 error "$dir5 should inherit the default layout from $dir4"
7500 }
7501 run_test 65n "don't inherit default layout from root for new subdirectories"
7502
7503 # bug 2543 - update blocks count on client
7504 test_66() {
7505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7506
7507         COUNT=${COUNT:-8}
7508         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7509         sync; sync_all_data; sync; sync_all_data
7510         cancel_lru_locks osc
7511         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7512         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7513 }
7514 run_test 66 "update inode blocks count on client ==============="
7515
7516 meminfo() {
7517         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7518 }
7519
7520 swap_used() {
7521         swapon -s | awk '($1 == "'$1'") { print $4 }'
7522 }
7523
7524 # bug5265, obdfilter oa2dentry return -ENOENT
7525 # #define OBD_FAIL_SRV_ENOENT 0x217
7526 test_69() {
7527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7528         remote_ost_nodsh && skip "remote OST with nodsh"
7529
7530         f="$DIR/$tfile"
7531         $LFS setstripe -c 1 -i 0 $f
7532
7533         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7534
7535         do_facet ost1 lctl set_param fail_loc=0x217
7536         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7537         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7538
7539         do_facet ost1 lctl set_param fail_loc=0
7540         $DIRECTIO write $f 0 2 || error "write error"
7541
7542         cancel_lru_locks osc
7543         $DIRECTIO read $f 0 1 || error "read error"
7544
7545         do_facet ost1 lctl set_param fail_loc=0x217
7546         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7547
7548         do_facet ost1 lctl set_param fail_loc=0
7549         rm -f $f
7550 }
7551 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7552
7553 test_71() {
7554         test_mkdir $DIR/$tdir
7555         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7556         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7557 }
7558 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7559
7560 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7562         [ "$RUNAS_ID" = "$UID" ] &&
7563                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7564         # Check that testing environment is properly set up. Skip if not
7565         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7566                 skip_env "User $RUNAS_ID does not exist - skipping"
7567
7568         touch $DIR/$tfile
7569         chmod 777 $DIR/$tfile
7570         chmod ug+s $DIR/$tfile
7571         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7572                 error "$RUNAS dd $DIR/$tfile failed"
7573         # See if we are still setuid/sgid
7574         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7575                 error "S/gid is not dropped on write"
7576         # Now test that MDS is updated too
7577         cancel_lru_locks mdc
7578         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7579                 error "S/gid is not dropped on MDS"
7580         rm -f $DIR/$tfile
7581 }
7582 run_test 72a "Test that remove suid works properly (bug5695) ===="
7583
7584 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7585         local perm
7586
7587         [ "$RUNAS_ID" = "$UID" ] &&
7588                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7589         [ "$RUNAS_ID" -eq 0 ] &&
7590                 skip_env "RUNAS_ID = 0 -- skipping"
7591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7592         # Check that testing environment is properly set up. Skip if not
7593         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7594                 skip_env "User $RUNAS_ID does not exist - skipping"
7595
7596         touch $DIR/${tfile}-f{g,u}
7597         test_mkdir $DIR/${tfile}-dg
7598         test_mkdir $DIR/${tfile}-du
7599         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7600         chmod g+s $DIR/${tfile}-{f,d}g
7601         chmod u+s $DIR/${tfile}-{f,d}u
7602         for perm in 777 2777 4777; do
7603                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7604                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7605                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7606                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7607         done
7608         true
7609 }
7610 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7611
7612 # bug 3462 - multiple simultaneous MDC requests
7613 test_73() {
7614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7615
7616         test_mkdir $DIR/d73-1
7617         test_mkdir $DIR/d73-2
7618         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7619         pid1=$!
7620
7621         lctl set_param fail_loc=0x80000129
7622         $MULTIOP $DIR/d73-1/f73-2 Oc &
7623         sleep 1
7624         lctl set_param fail_loc=0
7625
7626         $MULTIOP $DIR/d73-2/f73-3 Oc &
7627         pid3=$!
7628
7629         kill -USR1 $pid1
7630         wait $pid1 || return 1
7631
7632         sleep 25
7633
7634         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7635         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7636         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7637
7638         rm -rf $DIR/d73-*
7639 }
7640 run_test 73 "multiple MDC requests (should not deadlock)"
7641
7642 test_74a() { # bug 6149, 6184
7643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7644
7645         touch $DIR/f74a
7646         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7647         #
7648         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7649         # will spin in a tight reconnection loop
7650         $LCTL set_param fail_loc=0x8000030e
7651         # get any lock that won't be difficult - lookup works.
7652         ls $DIR/f74a
7653         $LCTL set_param fail_loc=0
7654         rm -f $DIR/f74a
7655         true
7656 }
7657 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7658
7659 test_74b() { # bug 13310
7660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7661
7662         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7663         #
7664         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7665         # will spin in a tight reconnection loop
7666         $LCTL set_param fail_loc=0x8000030e
7667         # get a "difficult" lock
7668         touch $DIR/f74b
7669         $LCTL set_param fail_loc=0
7670         rm -f $DIR/f74b
7671         true
7672 }
7673 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7674
7675 test_74c() {
7676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7677
7678         #define OBD_FAIL_LDLM_NEW_LOCK
7679         $LCTL set_param fail_loc=0x319
7680         touch $DIR/$tfile && error "touch successful"
7681         $LCTL set_param fail_loc=0
7682         true
7683 }
7684 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7685
7686 num_inodes() {
7687         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7688 }
7689
7690 test_76() { # Now for bug 20433, added originally in bug 1443
7691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7692
7693         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7694
7695         cancel_lru_locks osc
7696         BEFORE_INODES=$(num_inodes)
7697         echo "before inodes: $BEFORE_INODES"
7698         local COUNT=1000
7699         [ "$SLOW" = "no" ] && COUNT=100
7700         for i in $(seq $COUNT); do
7701                 touch $DIR/$tfile
7702                 rm -f $DIR/$tfile
7703         done
7704         cancel_lru_locks osc
7705         AFTER_INODES=$(num_inodes)
7706         echo "after inodes: $AFTER_INODES"
7707         local wait=0
7708         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7709                 sleep 2
7710                 AFTER_INODES=$(num_inodes)
7711                 wait=$((wait+2))
7712                 echo "wait $wait seconds inodes: $AFTER_INODES"
7713                 if [ $wait -gt 30 ]; then
7714                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7715                 fi
7716         done
7717 }
7718 run_test 76 "confirm clients recycle inodes properly ===="
7719
7720
7721 export ORIG_CSUM=""
7722 set_checksums()
7723 {
7724         # Note: in sptlrpc modes which enable its own bulk checksum, the
7725         # original crc32_le bulk checksum will be automatically disabled,
7726         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7727         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7728         # In this case set_checksums() will not be no-op, because sptlrpc
7729         # bulk checksum will be enabled all through the test.
7730
7731         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7732         lctl set_param -n osc.*.checksums $1
7733         return 0
7734 }
7735
7736 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7737                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7738 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7739                              tr -d [] | head -n1)}
7740 set_checksum_type()
7741 {
7742         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7743         log "set checksum type to $1"
7744         return 0
7745 }
7746 F77_TMP=$TMP/f77-temp
7747 F77SZ=8
7748 setup_f77() {
7749         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7750                 error "error writing to $F77_TMP"
7751 }
7752
7753 test_77a() { # bug 10889
7754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7755         $GSS && skip_env "could not run with gss"
7756
7757         [ ! -f $F77_TMP ] && setup_f77
7758         set_checksums 1
7759         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7760         set_checksums 0
7761         rm -f $DIR/$tfile
7762 }
7763 run_test 77a "normal checksum read/write operation"
7764
7765 test_77b() { # bug 10889
7766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7767         $GSS && skip_env "could not run with gss"
7768
7769         [ ! -f $F77_TMP ] && setup_f77
7770         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7771         $LCTL set_param fail_loc=0x80000409
7772         set_checksums 1
7773
7774         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7775                 error "dd error: $?"
7776         $LCTL set_param fail_loc=0
7777
7778         for algo in $CKSUM_TYPES; do
7779                 cancel_lru_locks osc
7780                 set_checksum_type $algo
7781                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7782                 $LCTL set_param fail_loc=0x80000408
7783                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7784                 $LCTL set_param fail_loc=0
7785         done
7786         set_checksums 0
7787         set_checksum_type $ORIG_CSUM_TYPE
7788         rm -f $DIR/$tfile
7789 }
7790 run_test 77b "checksum error on client write, read"
7791
7792 cleanup_77c() {
7793         trap 0
7794         set_checksums 0
7795         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7796         $check_ost &&
7797                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7798         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7799         $check_ost && [ -n "$ost_file_prefix" ] &&
7800                 do_facet ost1 rm -f ${ost_file_prefix}\*
7801 }
7802
7803 test_77c() {
7804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7805         $GSS && skip_env "could not run with gss"
7806         remote_ost_nodsh && skip "remote OST with nodsh"
7807
7808         local bad1
7809         local osc_file_prefix
7810         local osc_file
7811         local check_ost=false
7812         local ost_file_prefix
7813         local ost_file
7814         local orig_cksum
7815         local dump_cksum
7816         local fid
7817
7818         # ensure corruption will occur on first OSS/OST
7819         $LFS setstripe -i 0 $DIR/$tfile
7820
7821         [ ! -f $F77_TMP ] && setup_f77
7822         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7823                 error "dd write error: $?"
7824         fid=$($LFS path2fid $DIR/$tfile)
7825
7826         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7827         then
7828                 check_ost=true
7829                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7830                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7831         else
7832                 echo "OSS do not support bulk pages dump upon error"
7833         fi
7834
7835         osc_file_prefix=$($LCTL get_param -n debug_path)
7836         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7837
7838         trap cleanup_77c EXIT
7839
7840         set_checksums 1
7841         # enable bulk pages dump upon error on Client
7842         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7843         # enable bulk pages dump upon error on OSS
7844         $check_ost &&
7845                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7846
7847         # flush Client cache to allow next read to reach OSS
7848         cancel_lru_locks osc
7849
7850         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7851         $LCTL set_param fail_loc=0x80000408
7852         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7853         $LCTL set_param fail_loc=0
7854
7855         rm -f $DIR/$tfile
7856
7857         # check cksum dump on Client
7858         osc_file=$(ls ${osc_file_prefix}*)
7859         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7860         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7861         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7862         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7863         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7864                      cksum)
7865         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7866         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7867                 error "dump content does not match on Client"
7868
7869         $check_ost || skip "No need to check cksum dump on OSS"
7870
7871         # check cksum dump on OSS
7872         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7873         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7874         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7875         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7876         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7877                 error "dump content does not match on OSS"
7878
7879         cleanup_77c
7880 }
7881 run_test 77c "checksum error on client read with debug"
7882
7883 test_77d() { # bug 10889
7884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7885         $GSS && skip_env "could not run with gss"
7886
7887         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7888         $LCTL set_param fail_loc=0x80000409
7889         set_checksums 1
7890         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7891                 error "direct write: rc=$?"
7892         $LCTL set_param fail_loc=0
7893         set_checksums 0
7894
7895         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7896         $LCTL set_param fail_loc=0x80000408
7897         set_checksums 1
7898         cancel_lru_locks osc
7899         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7900                 error "direct read: rc=$?"
7901         $LCTL set_param fail_loc=0
7902         set_checksums 0
7903 }
7904 run_test 77d "checksum error on OST direct write, read"
7905
7906 test_77f() { # bug 10889
7907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7908         $GSS && skip_env "could not run with gss"
7909
7910         set_checksums 1
7911         for algo in $CKSUM_TYPES; do
7912                 cancel_lru_locks osc
7913                 set_checksum_type $algo
7914                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7915                 $LCTL set_param fail_loc=0x409
7916                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7917                         error "direct write succeeded"
7918                 $LCTL set_param fail_loc=0
7919         done
7920         set_checksum_type $ORIG_CSUM_TYPE
7921         set_checksums 0
7922 }
7923 run_test 77f "repeat checksum error on write (expect error)"
7924
7925 test_77g() { # bug 10889
7926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7927         $GSS && skip_env "could not run with gss"
7928         remote_ost_nodsh && skip "remote OST with nodsh"
7929
7930         [ ! -f $F77_TMP ] && setup_f77
7931
7932         local file=$DIR/$tfile
7933         stack_trap "rm -f $file" EXIT
7934
7935         $LFS setstripe -c 1 -i 0 $file
7936         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7937         do_facet ost1 lctl set_param fail_loc=0x8000021a
7938         set_checksums 1
7939         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7940                 error "write error: rc=$?"
7941         do_facet ost1 lctl set_param fail_loc=0
7942         set_checksums 0
7943
7944         cancel_lru_locks osc
7945         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7946         do_facet ost1 lctl set_param fail_loc=0x8000021b
7947         set_checksums 1
7948         cmp $F77_TMP $file || error "file compare failed"
7949         do_facet ost1 lctl set_param fail_loc=0
7950         set_checksums 0
7951 }
7952 run_test 77g "checksum error on OST write, read"
7953
7954 test_77k() { # LU-10906
7955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7956         $GSS && skip_env "could not run with gss"
7957
7958         local cksum_param="osc.$FSNAME*.checksums"
7959         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7960         local checksum
7961         local i
7962
7963         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7964         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7965         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7966                 EXIT
7967
7968         for i in 0 1; do
7969                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7970                         error "failed to set checksum=$i on MGS"
7971                 wait_update $HOSTNAME "$get_checksum" $i
7972                 #remount
7973                 echo "remount client, checksum should be $i"
7974                 remount_client $MOUNT || "failed to remount client"
7975                 checksum=$(eval $get_checksum)
7976                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7977         done
7978         # remove persistent param to avoid races with checksum mountopt below
7979         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7980                 error "failed to delete checksum on MGS"
7981
7982         for opt in "checksum" "nochecksum"; do
7983                 #remount with mount option
7984                 echo "remount client with option $opt, checksum should be $i"
7985                 umount_client $MOUNT || "failed to umount client"
7986                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7987                         "failed to mount client with option '$opt'"
7988                 checksum=$(eval $get_checksum)
7989                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7990                 i=$((i - 1))
7991         done
7992
7993         remount_client $MOUNT || "failed to remount client"
7994 }
7995 run_test 77k "enable/disable checksum correctly"
7996
7997 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7998 rm -f $F77_TMP
7999 unset F77_TMP
8000
8001 cleanup_test_78() {
8002         trap 0
8003         rm -f $DIR/$tfile
8004 }
8005
8006 test_78() { # bug 10901
8007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8008         remote_ost || skip_env "local OST"
8009
8010         NSEQ=5
8011         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8012         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8013         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8014         echo "MemTotal: $MEMTOTAL"
8015
8016         # reserve 256MB of memory for the kernel and other running processes,
8017         # and then take 1/2 of the remaining memory for the read/write buffers.
8018         if [ $MEMTOTAL -gt 512 ] ;then
8019                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8020         else
8021                 # for those poor memory-starved high-end clusters...
8022                 MEMTOTAL=$((MEMTOTAL / 2))
8023         fi
8024         echo "Mem to use for directio: $MEMTOTAL"
8025
8026         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8027         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8028         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8029         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8030                 head -n1)
8031         echo "Smallest OST: $SMALLESTOST"
8032         [[ $SMALLESTOST -lt 10240 ]] &&
8033                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8034
8035         trap cleanup_test_78 EXIT
8036
8037         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8038                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8039
8040         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8041         echo "File size: $F78SIZE"
8042         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8043         for i in $(seq 1 $NSEQ); do
8044                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8045                 echo directIO rdwr round $i of $NSEQ
8046                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8047         done
8048
8049         cleanup_test_78
8050 }
8051 run_test 78 "handle large O_DIRECT writes correctly ============"
8052
8053 test_79() { # bug 12743
8054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8055
8056         wait_delete_completed
8057
8058         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8059         BKFREE=$(calc_osc_kbytes kbytesfree)
8060         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8061
8062         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8063         DFTOTAL=`echo $STRING | cut -d, -f1`
8064         DFUSED=`echo $STRING  | cut -d, -f2`
8065         DFAVAIL=`echo $STRING | cut -d, -f3`
8066         DFFREE=$(($DFTOTAL - $DFUSED))
8067
8068         ALLOWANCE=$((64 * $OSTCOUNT))
8069
8070         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8071            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8072                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8073         fi
8074         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8075            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8076                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8077         fi
8078         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8079            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8080                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8081         fi
8082 }
8083 run_test 79 "df report consistency check ======================="
8084
8085 test_80() { # bug 10718
8086         remote_ost_nodsh && skip "remote OST with nodsh"
8087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8088
8089         # relax strong synchronous semantics for slow backends like ZFS
8090         local soc="obdfilter.*.sync_on_lock_cancel"
8091         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8092         local hosts=
8093         if [ "$soc_old" != "never" ] &&
8094                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8095                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8096                                 facet_active_host $host; done | sort -u)
8097                         do_nodes $hosts lctl set_param $soc=never
8098         fi
8099
8100         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8101         sync; sleep 1; sync
8102         local BEFORE=`date +%s`
8103         cancel_lru_locks osc
8104         local AFTER=`date +%s`
8105         local DIFF=$((AFTER-BEFORE))
8106         if [ $DIFF -gt 1 ] ; then
8107                 error "elapsed for 1M@1T = $DIFF"
8108         fi
8109
8110         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8111
8112         rm -f $DIR/$tfile
8113 }
8114 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8115
8116 test_81a() { # 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         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8122         do_facet ost1 lctl set_param fail_loc=0x80000228
8123
8124         # write should trigger a retry and success
8125         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8126         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8127         RC=$?
8128         if [ $RC -ne 0 ] ; then
8129                 error "write should success, but failed for $RC"
8130         fi
8131 }
8132 run_test 81a "OST should retry write when get -ENOSPC ==============="
8133
8134 test_81b() { # LU-456
8135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8136         remote_ost_nodsh && skip "remote OST with nodsh"
8137
8138         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8139         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8140         do_facet ost1 lctl set_param fail_loc=0x228
8141
8142         # write should retry several times and return -ENOSPC finally
8143         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8144         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8145         RC=$?
8146         ENOSPC=28
8147         if [ $RC -ne $ENOSPC ] ; then
8148                 error "dd should fail for -ENOSPC, but succeed."
8149         fi
8150 }
8151 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8152
8153 test_82() { # LU-1031
8154         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8155         local gid1=14091995
8156         local gid2=16022000
8157
8158         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8159         local MULTIPID1=$!
8160         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8161         local MULTIPID2=$!
8162         kill -USR1 $MULTIPID2
8163         sleep 2
8164         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8165                 error "First grouplock does not block second one"
8166         else
8167                 echo "Second grouplock blocks first one"
8168         fi
8169         kill -USR1 $MULTIPID1
8170         wait $MULTIPID1
8171         wait $MULTIPID2
8172 }
8173 run_test 82 "Basic grouplock test"
8174
8175 test_99() {
8176         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8177
8178         test_mkdir $DIR/$tdir.cvsroot
8179         chown $RUNAS_ID $DIR/$tdir.cvsroot
8180
8181         cd $TMP
8182         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8183
8184         cd /etc/init.d
8185         # some versions of cvs import exit(1) when asked to import links or
8186         # files they can't read.  ignore those files.
8187         local toignore=$(find . -type l -printf '-I %f\n' -o \
8188                          ! -perm /4 -printf '-I %f\n')
8189         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8190                 $tdir.reposname vtag rtag
8191
8192         cd $DIR
8193         test_mkdir $DIR/$tdir.reposname
8194         chown $RUNAS_ID $DIR/$tdir.reposname
8195         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8196
8197         cd $DIR/$tdir.reposname
8198         $RUNAS touch foo99
8199         $RUNAS cvs add -m 'addmsg' foo99
8200         $RUNAS cvs update
8201         $RUNAS cvs commit -m 'nomsg' foo99
8202         rm -fr $DIR/$tdir.cvsroot
8203 }
8204 run_test 99 "cvs strange file/directory operations"
8205
8206 test_100() {
8207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8208         [[ "$NETTYPE" =~ tcp ]] ||
8209                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8210         remote_ost_nodsh && skip "remote OST with nodsh"
8211         remote_mds_nodsh && skip "remote MDS with nodsh"
8212         remote_servers ||
8213                 skip "useless for local single node setup"
8214
8215         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8216                 [ "$PROT" != "tcp" ] && continue
8217                 RPORT=$(echo $REMOTE | cut -d: -f2)
8218                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8219
8220                 rc=0
8221                 LPORT=`echo $LOCAL | cut -d: -f2`
8222                 if [ $LPORT -ge 1024 ]; then
8223                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8224                         netstat -tna
8225                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8226                 fi
8227         done
8228         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8229 }
8230 run_test 100 "check local port using privileged port ==========="
8231
8232 function get_named_value()
8233 {
8234     local tag
8235
8236     tag=$1
8237     while read ;do
8238         line=$REPLY
8239         case $line in
8240         $tag*)
8241             echo $line | sed "s/^$tag[ ]*//"
8242             break
8243             ;;
8244         esac
8245     done
8246 }
8247
8248 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8249                    awk '/^max_cached_mb/ { print $2 }')
8250
8251 cleanup_101a() {
8252         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8253         trap 0
8254 }
8255
8256 test_101a() {
8257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8258         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
8259
8260         local s
8261         local discard
8262         local nreads=10000
8263         local cache_limit=32
8264
8265         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8266         trap cleanup_101a EXIT
8267         $LCTL set_param -n llite.*.read_ahead_stats 0
8268         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8269
8270         #
8271         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8272         #
8273         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8274         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8275
8276         discard=0
8277         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8278                 get_named_value 'read but discarded' | cut -d" " -f1); do
8279                         discard=$(($discard + $s))
8280         done
8281         cleanup_101a
8282
8283         if [[ $(($discard * 10)) -gt $nreads ]]; then
8284                 $LCTL get_param osc.*-osc*.rpc_stats
8285                 $LCTL get_param llite.*.read_ahead_stats
8286                 error "too many ($discard) discarded pages"
8287         fi
8288         rm -f $DIR/$tfile || true
8289 }
8290 run_test 101a "check read-ahead for random reads"
8291
8292 setup_test101bc() {
8293         test_mkdir $DIR/$tdir
8294         local ssize=$1
8295         local FILE_LENGTH=$2
8296         STRIPE_OFFSET=0
8297
8298         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8299
8300         local list=$(comma_list $(osts_nodes))
8301         set_osd_param $list '' read_cache_enable 0
8302         set_osd_param $list '' writethrough_cache_enable 0
8303
8304         trap cleanup_test101bc EXIT
8305         # prepare the read-ahead file
8306         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8307
8308         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8309                                 count=$FILE_SIZE_MB 2> /dev/null
8310
8311 }
8312
8313 cleanup_test101bc() {
8314         trap 0
8315         rm -rf $DIR/$tdir
8316         rm -f $DIR/$tfile
8317
8318         local list=$(comma_list $(osts_nodes))
8319         set_osd_param $list '' read_cache_enable 1
8320         set_osd_param $list '' writethrough_cache_enable 1
8321 }
8322
8323 calc_total() {
8324         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8325 }
8326
8327 ra_check_101() {
8328         local READ_SIZE=$1
8329         local STRIPE_SIZE=$2
8330         local FILE_LENGTH=$3
8331         local RA_INC=1048576
8332         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8333         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8334                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8335         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8336                         get_named_value 'read but discarded' |
8337                         cut -d" " -f1 | calc_total)
8338         if [[ $DISCARD -gt $discard_limit ]]; then
8339                 $LCTL get_param llite.*.read_ahead_stats
8340                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8341         else
8342                 echo "Read-ahead success for size ${READ_SIZE}"
8343         fi
8344 }
8345
8346 test_101b() {
8347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8348         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8349
8350         local STRIPE_SIZE=1048576
8351         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8352
8353         if [ $SLOW == "yes" ]; then
8354                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8355         else
8356                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8357         fi
8358
8359         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8360
8361         # prepare the read-ahead file
8362         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8363         cancel_lru_locks osc
8364         for BIDX in 2 4 8 16 32 64 128 256
8365         do
8366                 local BSIZE=$((BIDX*4096))
8367                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8368                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8369                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8370                 $LCTL set_param -n llite.*.read_ahead_stats 0
8371                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8372                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8373                 cancel_lru_locks osc
8374                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8375         done
8376         cleanup_test101bc
8377         true
8378 }
8379 run_test 101b "check stride-io mode read-ahead ================="
8380
8381 test_101c() {
8382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8383
8384         local STRIPE_SIZE=1048576
8385         local FILE_LENGTH=$((STRIPE_SIZE*100))
8386         local nreads=10000
8387         local rsize=65536
8388         local osc_rpc_stats
8389
8390         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8391
8392         cancel_lru_locks osc
8393         $LCTL set_param osc.*.rpc_stats 0
8394         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8395         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8396                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8397                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8398                 local size
8399
8400                 if [ $lines -le 20 ]; then
8401                         continue
8402                 fi
8403                 for size in 1 2 4 8; do
8404                         local rpc=$(echo "$stats" |
8405                                     awk '($1 == "'$size':") {print $2; exit; }')
8406                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8407                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8408                 done
8409                 echo "$osc_rpc_stats check passed!"
8410         done
8411         cleanup_test101bc
8412         true
8413 }
8414 run_test 101c "check stripe_size aligned read-ahead ================="
8415
8416 set_read_ahead() {
8417         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8418         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8419 }
8420
8421 test_101d() {
8422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8423
8424         local file=$DIR/$tfile
8425         local sz_MB=${FILESIZE_101d:-500}
8426         local ra_MB=${READAHEAD_MB:-40}
8427
8428         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8429         [ $free_MB -lt $sz_MB ] &&
8430                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8431
8432         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8433         $LFS setstripe -c -1 $file || error "setstripe failed"
8434
8435         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8436         echo Cancel LRU locks on lustre client to flush the client cache
8437         cancel_lru_locks osc
8438
8439         echo Disable read-ahead
8440         local old_READAHEAD=$(set_read_ahead 0)
8441
8442         echo Reading the test file $file with read-ahead disabled
8443         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8444
8445         echo Cancel LRU locks on lustre client to flush the client cache
8446         cancel_lru_locks osc
8447         echo Enable read-ahead with ${ra_MB}MB
8448         set_read_ahead $ra_MB
8449
8450         echo Reading the test file $file with read-ahead enabled
8451         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8452
8453         echo "read-ahead disabled time read $raOFF"
8454         echo "read-ahead enabled  time read $raON"
8455
8456         set_read_ahead $old_READAHEAD
8457         rm -f $file
8458         wait_delete_completed
8459
8460         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8461                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8462 }
8463 run_test 101d "file read with and without read-ahead enabled"
8464
8465 test_101e() {
8466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8467
8468         local file=$DIR/$tfile
8469         local size_KB=500  #KB
8470         local count=100
8471         local bsize=1024
8472
8473         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8474         local need_KB=$((count * size_KB))
8475         [[ $free_KB -le $need_KB ]] &&
8476                 skip_env "Need free space $need_KB, have $free_KB"
8477
8478         echo "Creating $count ${size_KB}K test files"
8479         for ((i = 0; i < $count; i++)); do
8480                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8481         done
8482
8483         echo "Cancel LRU locks on lustre client to flush the client cache"
8484         cancel_lru_locks $OSC
8485
8486         echo "Reset readahead stats"
8487         $LCTL set_param -n llite.*.read_ahead_stats 0
8488
8489         for ((i = 0; i < $count; i++)); do
8490                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8491         done
8492
8493         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8494                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8495
8496         for ((i = 0; i < $count; i++)); do
8497                 rm -rf $file.$i 2>/dev/null
8498         done
8499
8500         #10000 means 20% reads are missing in readahead
8501         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8502 }
8503 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8504
8505 test_101f() {
8506         which iozone || skip_env "no iozone installed"
8507
8508         local old_debug=$($LCTL get_param debug)
8509         old_debug=${old_debug#*=}
8510         $LCTL set_param debug="reada mmap"
8511
8512         # create a test file
8513         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8514
8515         echo Cancel LRU locks on lustre client to flush the client cache
8516         cancel_lru_locks osc
8517
8518         echo Reset readahead stats
8519         $LCTL set_param -n llite.*.read_ahead_stats 0
8520
8521         echo mmap read the file with small block size
8522         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8523                 > /dev/null 2>&1
8524
8525         echo checking missing pages
8526         $LCTL get_param llite.*.read_ahead_stats
8527         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8528                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8529
8530         $LCTL set_param debug="$old_debug"
8531         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8532         rm -f $DIR/$tfile
8533 }
8534 run_test 101f "check mmap read performance"
8535
8536 test_101g_brw_size_test() {
8537         local mb=$1
8538         local pages=$((mb * 1048576 / PAGE_SIZE))
8539         local file=$DIR/$tfile
8540
8541         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8542                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8543         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8544                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8545                         return 2
8546         done
8547
8548         stack_trap "rm -f $file" EXIT
8549         $LCTL set_param -n osc.*.rpc_stats=0
8550
8551         # 10 RPCs should be enough for the test
8552         local count=10
8553         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8554                 { error "dd write ${mb} MB blocks failed"; return 3; }
8555         cancel_lru_locks osc
8556         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8557                 { error "dd write ${mb} MB blocks failed"; return 4; }
8558
8559         # calculate number of full-sized read and write RPCs
8560         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8561                 sed -n '/pages per rpc/,/^$/p' |
8562                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8563                 END { print reads,writes }'))
8564         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8565                 return 5
8566         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8567                 return 6
8568
8569         return 0
8570 }
8571
8572 test_101g() {
8573         remote_ost_nodsh && skip "remote OST with nodsh"
8574
8575         local rpcs
8576         local osts=$(get_facets OST)
8577         local list=$(comma_list $(osts_nodes))
8578         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8579         local brw_size="obdfilter.*.brw_size"
8580
8581         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8582
8583         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8584
8585         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8586                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8587                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8588            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8589                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8590                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8591
8592                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8593                         suffix="M"
8594
8595                 if [[ $orig_mb -lt 16 ]]; then
8596                         save_lustre_params $osts "$brw_size" > $p
8597                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8598                                 error "set 16MB RPC size failed"
8599
8600                         echo "remount client to enable new RPC size"
8601                         remount_client $MOUNT || error "remount_client failed"
8602                 fi
8603
8604                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8605                 # should be able to set brw_size=12, but no rpc_stats for that
8606                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8607         fi
8608
8609         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8610
8611         if [[ $orig_mb -lt 16 ]]; then
8612                 restore_lustre_params < $p
8613                 remount_client $MOUNT || error "remount_client restore failed"
8614         fi
8615
8616         rm -f $p $DIR/$tfile
8617 }
8618 run_test 101g "Big bulk(4/16 MiB) readahead"
8619
8620 test_101h() {
8621         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8622
8623         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
8624                 error "dd 70M file failed"
8625         echo Cancel LRU locks on lustre client to flush the client cache
8626         cancel_lru_locks osc
8627
8628         echo "Reset readahead stats"
8629         $LCTL set_param -n llite.*.read_ahead_stats 0
8630
8631         echo "Read 10M of data but cross 64M bundary"
8632         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
8633         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8634                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8635         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
8636         rm -f $p $DIR/$tfile
8637 }
8638 run_test 101h "Readahead should cover current read window"
8639
8640 setup_test102() {
8641         test_mkdir $DIR/$tdir
8642         chown $RUNAS_ID $DIR/$tdir
8643         STRIPE_SIZE=65536
8644         STRIPE_OFFSET=1
8645         STRIPE_COUNT=$OSTCOUNT
8646         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8647
8648         trap cleanup_test102 EXIT
8649         cd $DIR
8650         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8651         cd $DIR/$tdir
8652         for num in 1 2 3 4; do
8653                 for count in $(seq 1 $STRIPE_COUNT); do
8654                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8655                                 local size=`expr $STRIPE_SIZE \* $num`
8656                                 local file=file"$num-$idx-$count"
8657                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8658                         done
8659                 done
8660         done
8661
8662         cd $DIR
8663         $1 tar cf $TMP/f102.tar $tdir --xattrs
8664 }
8665
8666 cleanup_test102() {
8667         trap 0
8668         rm -f $TMP/f102.tar
8669         rm -rf $DIR/d0.sanity/d102
8670 }
8671
8672 test_102a() {
8673         [ "$UID" != 0 ] && skip "must run as root"
8674         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8675                 skip_env "must have user_xattr"
8676
8677         [ -z "$(which setfattr 2>/dev/null)" ] &&
8678                 skip_env "could not find setfattr"
8679
8680         local testfile=$DIR/$tfile
8681
8682         touch $testfile
8683         echo "set/get xattr..."
8684         setfattr -n trusted.name1 -v value1 $testfile ||
8685                 error "setfattr -n trusted.name1=value1 $testfile failed"
8686         getfattr -n trusted.name1 $testfile 2> /dev/null |
8687           grep "trusted.name1=.value1" ||
8688                 error "$testfile missing trusted.name1=value1"
8689
8690         setfattr -n user.author1 -v author1 $testfile ||
8691                 error "setfattr -n user.author1=author1 $testfile failed"
8692         getfattr -n user.author1 $testfile 2> /dev/null |
8693           grep "user.author1=.author1" ||
8694                 error "$testfile missing trusted.author1=author1"
8695
8696         echo "listxattr..."
8697         setfattr -n trusted.name2 -v value2 $testfile ||
8698                 error "$testfile unable to set trusted.name2"
8699         setfattr -n trusted.name3 -v value3 $testfile ||
8700                 error "$testfile unable to set trusted.name3"
8701         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8702             grep "trusted.name" | wc -l) -eq 3 ] ||
8703                 error "$testfile missing 3 trusted.name xattrs"
8704
8705         setfattr -n user.author2 -v author2 $testfile ||
8706                 error "$testfile unable to set user.author2"
8707         setfattr -n user.author3 -v author3 $testfile ||
8708                 error "$testfile unable to set user.author3"
8709         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8710             grep "user.author" | wc -l) -eq 3 ] ||
8711                 error "$testfile missing 3 user.author xattrs"
8712
8713         echo "remove xattr..."
8714         setfattr -x trusted.name1 $testfile ||
8715                 error "$testfile error deleting trusted.name1"
8716         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8717                 error "$testfile did not delete trusted.name1 xattr"
8718
8719         setfattr -x user.author1 $testfile ||
8720                 error "$testfile error deleting user.author1"
8721         echo "set lustre special xattr ..."
8722         $LFS setstripe -c1 $testfile
8723         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8724                 awk -F "=" '/trusted.lov/ { print $2 }' )
8725         setfattr -n "trusted.lov" -v $lovea $testfile ||
8726                 error "$testfile doesn't ignore setting trusted.lov again"
8727         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8728                 error "$testfile allow setting invalid trusted.lov"
8729         rm -f $testfile
8730 }
8731 run_test 102a "user xattr test =================================="
8732
8733 test_102b() {
8734         [ -z "$(which setfattr 2>/dev/null)" ] &&
8735                 skip_env "could not find setfattr"
8736         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8737
8738         # b10930: get/set/list trusted.lov xattr
8739         echo "get/set/list trusted.lov xattr ..."
8740         local testfile=$DIR/$tfile
8741         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8742                 error "setstripe failed"
8743         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8744                 error "getstripe failed"
8745         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8746                 error "can't get trusted.lov from $testfile"
8747
8748         local testfile2=${testfile}2
8749         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8750                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8751
8752         $MCREATE $testfile2
8753         setfattr -n trusted.lov -v $value $testfile2
8754         local stripe_size=$($LFS getstripe -S $testfile2)
8755         local stripe_count=$($LFS getstripe -c $testfile2)
8756         [[ $stripe_size -eq 65536 ]] ||
8757                 error "stripe size $stripe_size != 65536"
8758         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8759                 error "stripe count $stripe_count != $STRIPECOUNT"
8760         rm -f $DIR/$tfile
8761 }
8762 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8763
8764 test_102c() {
8765         [ -z "$(which setfattr 2>/dev/null)" ] &&
8766                 skip_env "could not find setfattr"
8767         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8768
8769         # b10930: get/set/list lustre.lov xattr
8770         echo "get/set/list lustre.lov xattr ..."
8771         test_mkdir $DIR/$tdir
8772         chown $RUNAS_ID $DIR/$tdir
8773         local testfile=$DIR/$tdir/$tfile
8774         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8775                 error "setstripe failed"
8776         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8777                 error "getstripe failed"
8778         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8779         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8780
8781         local testfile2=${testfile}2
8782         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8783                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8784
8785         $RUNAS $MCREATE $testfile2
8786         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8787         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8788         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8789         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8790         [ $stripe_count -eq $STRIPECOUNT ] ||
8791                 error "stripe count $stripe_count != $STRIPECOUNT"
8792 }
8793 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8794
8795 compare_stripe_info1() {
8796         local stripe_index_all_zero=true
8797
8798         for num in 1 2 3 4; do
8799                 for count in $(seq 1 $STRIPE_COUNT); do
8800                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8801                                 local size=$((STRIPE_SIZE * num))
8802                                 local file=file"$num-$offset-$count"
8803                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8804                                 [[ $stripe_size -ne $size ]] &&
8805                                     error "$file: size $stripe_size != $size"
8806                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8807                                 # allow fewer stripes to be created, ORI-601
8808                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8809                                     error "$file: count $stripe_count != $count"
8810                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8811                                 [[ $stripe_index -ne 0 ]] &&
8812                                         stripe_index_all_zero=false
8813                         done
8814                 done
8815         done
8816         $stripe_index_all_zero &&
8817                 error "all files are being extracted starting from OST index 0"
8818         return 0
8819 }
8820
8821 have_xattrs_include() {
8822         tar --help | grep -q xattrs-include &&
8823                 echo --xattrs-include="lustre.*"
8824 }
8825
8826 test_102d() {
8827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8828         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8829
8830         XINC=$(have_xattrs_include)
8831         setup_test102
8832         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8833         cd $DIR/$tdir/$tdir
8834         compare_stripe_info1
8835 }
8836 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8837
8838 test_102f() {
8839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8840         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8841
8842         XINC=$(have_xattrs_include)
8843         setup_test102
8844         test_mkdir $DIR/$tdir.restore
8845         cd $DIR
8846         tar cf - --xattrs $tdir | tar xf - \
8847                 -C $DIR/$tdir.restore --xattrs $XINC
8848         cd $DIR/$tdir.restore/$tdir
8849         compare_stripe_info1
8850 }
8851 run_test 102f "tar copy files, not keep osts"
8852
8853 grow_xattr() {
8854         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8855                 skip "must have user_xattr"
8856         [ -z "$(which setfattr 2>/dev/null)" ] &&
8857                 skip_env "could not find setfattr"
8858         [ -z "$(which getfattr 2>/dev/null)" ] &&
8859                 skip_env "could not find getfattr"
8860
8861         local xsize=${1:-1024}  # in bytes
8862         local file=$DIR/$tfile
8863         local value="$(generate_string $xsize)"
8864         local xbig=trusted.big
8865         local toobig=$2
8866
8867         touch $file
8868         log "save $xbig on $file"
8869         if [ -z "$toobig" ]
8870         then
8871                 setfattr -n $xbig -v $value $file ||
8872                         error "saving $xbig on $file failed"
8873         else
8874                 setfattr -n $xbig -v $value $file &&
8875                         error "saving $xbig on $file succeeded"
8876                 return 0
8877         fi
8878
8879         local orig=$(get_xattr_value $xbig $file)
8880         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8881
8882         local xsml=trusted.sml
8883         log "save $xsml on $file"
8884         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8885
8886         local new=$(get_xattr_value $xbig $file)
8887         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8888
8889         log "grow $xsml on $file"
8890         setfattr -n $xsml -v "$value" $file ||
8891                 error "growing $xsml on $file failed"
8892
8893         new=$(get_xattr_value $xbig $file)
8894         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8895         log "$xbig still valid after growing $xsml"
8896
8897         rm -f $file
8898 }
8899
8900 test_102h() { # bug 15777
8901         grow_xattr 1024
8902 }
8903 run_test 102h "grow xattr from inside inode to external block"
8904
8905 test_102ha() {
8906         large_xattr_enabled || skip_env "ea_inode feature disabled"
8907
8908         echo "setting xattr of max xattr size: $(max_xattr_size)"
8909         grow_xattr $(max_xattr_size)
8910
8911         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8912         echo "This should fail:"
8913         grow_xattr $(($(max_xattr_size) + 10)) 1
8914 }
8915 run_test 102ha "grow xattr from inside inode to external inode"
8916
8917 test_102i() { # bug 17038
8918         [ -z "$(which getfattr 2>/dev/null)" ] &&
8919                 skip "could not find getfattr"
8920
8921         touch $DIR/$tfile
8922         ln -s $DIR/$tfile $DIR/${tfile}link
8923         getfattr -n trusted.lov $DIR/$tfile ||
8924                 error "lgetxattr on $DIR/$tfile failed"
8925         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8926                 grep -i "no such attr" ||
8927                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8928         rm -f $DIR/$tfile $DIR/${tfile}link
8929 }
8930 run_test 102i "lgetxattr test on symbolic link ============"
8931
8932 test_102j() {
8933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8934         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8935
8936         XINC=$(have_xattrs_include)
8937         setup_test102 "$RUNAS"
8938         chown $RUNAS_ID $DIR/$tdir
8939         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8940         cd $DIR/$tdir/$tdir
8941         compare_stripe_info1 "$RUNAS"
8942 }
8943 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8944
8945 test_102k() {
8946         [ -z "$(which setfattr 2>/dev/null)" ] &&
8947                 skip "could not find setfattr"
8948
8949         touch $DIR/$tfile
8950         # b22187 just check that does not crash for regular file.
8951         setfattr -n trusted.lov $DIR/$tfile
8952         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8953         local test_kdir=$DIR/$tdir
8954         test_mkdir $test_kdir
8955         local default_size=$($LFS getstripe -S $test_kdir)
8956         local default_count=$($LFS getstripe -c $test_kdir)
8957         local default_offset=$($LFS getstripe -i $test_kdir)
8958         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8959                 error 'dir setstripe failed'
8960         setfattr -n trusted.lov $test_kdir
8961         local stripe_size=$($LFS getstripe -S $test_kdir)
8962         local stripe_count=$($LFS getstripe -c $test_kdir)
8963         local stripe_offset=$($LFS getstripe -i $test_kdir)
8964         [ $stripe_size -eq $default_size ] ||
8965                 error "stripe size $stripe_size != $default_size"
8966         [ $stripe_count -eq $default_count ] ||
8967                 error "stripe count $stripe_count != $default_count"
8968         [ $stripe_offset -eq $default_offset ] ||
8969                 error "stripe offset $stripe_offset != $default_offset"
8970         rm -rf $DIR/$tfile $test_kdir
8971 }
8972 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8973
8974 test_102l() {
8975         [ -z "$(which getfattr 2>/dev/null)" ] &&
8976                 skip "could not find getfattr"
8977
8978         # LU-532 trusted. xattr is invisible to non-root
8979         local testfile=$DIR/$tfile
8980
8981         touch $testfile
8982
8983         echo "listxattr as user..."
8984         chown $RUNAS_ID $testfile
8985         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8986             grep -q "trusted" &&
8987                 error "$testfile trusted xattrs are user visible"
8988
8989         return 0;
8990 }
8991 run_test 102l "listxattr size test =================================="
8992
8993 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8994         local path=$DIR/$tfile
8995         touch $path
8996
8997         listxattr_size_check $path || error "listattr_size_check $path failed"
8998 }
8999 run_test 102m "Ensure listxattr fails on small bufffer ========"
9000
9001 cleanup_test102
9002
9003 getxattr() { # getxattr path name
9004         # Return the base64 encoding of the value of xattr name on path.
9005         local path=$1
9006         local name=$2
9007
9008         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9009         # file: $path
9010         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9011         #
9012         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9013
9014         getfattr --absolute-names --encoding=base64 --name=$name $path |
9015                 awk -F= -v name=$name '$1 == name {
9016                         print substr($0, index($0, "=") + 1);
9017         }'
9018 }
9019
9020 test_102n() { # LU-4101 mdt: protect internal xattrs
9021         [ -z "$(which setfattr 2>/dev/null)" ] &&
9022                 skip "could not find setfattr"
9023         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9024         then
9025                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9026         fi
9027
9028         local file0=$DIR/$tfile.0
9029         local file1=$DIR/$tfile.1
9030         local xattr0=$TMP/$tfile.0
9031         local xattr1=$TMP/$tfile.1
9032         local namelist="lov lma lmv link fid version som hsm"
9033         local name
9034         local value
9035
9036         rm -rf $file0 $file1 $xattr0 $xattr1
9037         touch $file0 $file1
9038
9039         # Get 'before' xattrs of $file1.
9040         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9041
9042         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9043                 namelist+=" lfsck_namespace"
9044         for name in $namelist; do
9045                 # Try to copy xattr from $file0 to $file1.
9046                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9047
9048                 setfattr --name=trusted.$name --value="$value" $file1 ||
9049                         error "setxattr 'trusted.$name' failed"
9050
9051                 # Try to set a garbage xattr.
9052                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9053
9054                 if [[ x$name == "xlov" ]]; then
9055                         setfattr --name=trusted.lov --value="$value" $file1 &&
9056                         error "setxattr invalid 'trusted.lov' success"
9057                 else
9058                         setfattr --name=trusted.$name --value="$value" $file1 ||
9059                                 error "setxattr invalid 'trusted.$name' failed"
9060                 fi
9061
9062                 # Try to remove the xattr from $file1. We don't care if this
9063                 # appears to succeed or fail, we just don't want there to be
9064                 # any changes or crashes.
9065                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9066         done
9067
9068         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9069         then
9070                 name="lfsck_ns"
9071                 # Try to copy xattr from $file0 to $file1.
9072                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9073
9074                 setfattr --name=trusted.$name --value="$value" $file1 ||
9075                         error "setxattr 'trusted.$name' failed"
9076
9077                 # Try to set a garbage xattr.
9078                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9079
9080                 setfattr --name=trusted.$name --value="$value" $file1 ||
9081                         error "setxattr 'trusted.$name' failed"
9082
9083                 # Try to remove the xattr from $file1. We don't care if this
9084                 # appears to succeed or fail, we just don't want there to be
9085                 # any changes or crashes.
9086                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9087         fi
9088
9089         # Get 'after' xattrs of file1.
9090         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9091
9092         if ! diff $xattr0 $xattr1; then
9093                 error "before and after xattrs of '$file1' differ"
9094         fi
9095
9096         rm -rf $file0 $file1 $xattr0 $xattr1
9097
9098         return 0
9099 }
9100 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9101
9102 test_102p() { # LU-4703 setxattr did not check ownership
9103         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9104                 skip "MDS needs to be at least 2.5.56"
9105
9106         local testfile=$DIR/$tfile
9107
9108         touch $testfile
9109
9110         echo "setfacl as user..."
9111         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9112         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9113
9114         echo "setfattr as user..."
9115         setfacl -m "u:$RUNAS_ID:---" $testfile
9116         $RUNAS setfattr -x system.posix_acl_access $testfile
9117         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9118 }
9119 run_test 102p "check setxattr(2) correctly fails without permission"
9120
9121 test_102q() {
9122         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9123                 skip "MDS needs to be at least 2.6.92"
9124
9125         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9126 }
9127 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9128
9129 test_102r() {
9130         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9131                 skip "MDS needs to be at least 2.6.93"
9132
9133         touch $DIR/$tfile || error "touch"
9134         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9135         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9136         rm $DIR/$tfile || error "rm"
9137
9138         #normal directory
9139         mkdir -p $DIR/$tdir || error "mkdir"
9140         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9141         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9142         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9143                 error "$testfile error deleting user.author1"
9144         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9145                 grep "user.$(basename $tdir)" &&
9146                 error "$tdir did not delete user.$(basename $tdir)"
9147         rmdir $DIR/$tdir || error "rmdir"
9148
9149         #striped directory
9150         test_mkdir $DIR/$tdir
9151         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9152         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9153         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9154                 error "$testfile error deleting user.author1"
9155         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9156                 grep "user.$(basename $tdir)" &&
9157                 error "$tdir did not delete user.$(basename $tdir)"
9158         rmdir $DIR/$tdir || error "rm striped dir"
9159 }
9160 run_test 102r "set EAs with empty values"
9161
9162 test_102s() {
9163         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9164                 skip "MDS needs to be at least 2.11.52"
9165
9166         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9167
9168         save_lustre_params client "llite.*.xattr_cache" > $save
9169
9170         for cache in 0 1; do
9171                 lctl set_param llite.*.xattr_cache=$cache
9172
9173                 rm -f $DIR/$tfile
9174                 touch $DIR/$tfile || error "touch"
9175                 for prefix in lustre security system trusted user; do
9176                         # Note getxattr() may fail with 'Operation not
9177                         # supported' or 'No such attribute' depending
9178                         # on prefix and cache.
9179                         getfattr -n $prefix.n102s $DIR/$tfile &&
9180                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9181                 done
9182         done
9183
9184         restore_lustre_params < $save
9185 }
9186 run_test 102s "getting nonexistent xattrs should fail"
9187
9188 test_102t() {
9189         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9190                 skip "MDS needs to be at least 2.11.52"
9191
9192         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9193
9194         save_lustre_params client "llite.*.xattr_cache" > $save
9195
9196         for cache in 0 1; do
9197                 lctl set_param llite.*.xattr_cache=$cache
9198
9199                 for buf_size in 0 256; do
9200                         rm -f $DIR/$tfile
9201                         touch $DIR/$tfile || error "touch"
9202                         setfattr -n user.multiop $DIR/$tfile
9203                         $MULTIOP $DIR/$tfile oa$buf_size ||
9204                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9205                 done
9206         done
9207
9208         restore_lustre_params < $save
9209 }
9210 run_test 102t "zero length xattr values handled correctly"
9211
9212 run_acl_subtest()
9213 {
9214     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9215     return $?
9216 }
9217
9218 test_103a() {
9219         [ "$UID" != 0 ] && skip "must run as root"
9220         $GSS && skip_env "could not run under gss"
9221         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9222                 skip_env "must have acl enabled"
9223         [ -z "$(which setfacl 2>/dev/null)" ] &&
9224                 skip_env "could not find setfacl"
9225         remote_mds_nodsh && skip "remote MDS with nodsh"
9226
9227         gpasswd -a daemon bin                           # LU-5641
9228         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9229
9230         declare -a identity_old
9231
9232         for num in $(seq $MDSCOUNT); do
9233                 switch_identity $num true || identity_old[$num]=$?
9234         done
9235
9236         SAVE_UMASK=$(umask)
9237         umask 0022
9238         mkdir -p $DIR/$tdir
9239         cd $DIR/$tdir
9240
9241         echo "performing cp ..."
9242         run_acl_subtest cp || error "run_acl_subtest cp failed"
9243         echo "performing getfacl-noacl..."
9244         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9245         echo "performing misc..."
9246         run_acl_subtest misc || error  "misc test failed"
9247         echo "performing permissions..."
9248         run_acl_subtest permissions || error "permissions failed"
9249         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9250         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9251                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9252                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9253         then
9254                 echo "performing permissions xattr..."
9255                 run_acl_subtest permissions_xattr ||
9256                         error "permissions_xattr failed"
9257         fi
9258         echo "performing setfacl..."
9259         run_acl_subtest setfacl || error  "setfacl test failed"
9260
9261         # inheritance test got from HP
9262         echo "performing inheritance..."
9263         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9264         chmod +x make-tree || error "chmod +x failed"
9265         run_acl_subtest inheritance || error "inheritance test failed"
9266         rm -f make-tree
9267
9268         echo "LU-974 ignore umask when acl is enabled..."
9269         run_acl_subtest 974 || error "LU-974 umask test failed"
9270         if [ $MDSCOUNT -ge 2 ]; then
9271                 run_acl_subtest 974_remote ||
9272                         error "LU-974 umask test failed under remote dir"
9273         fi
9274
9275         echo "LU-2561 newly created file is same size as directory..."
9276         if [ "$mds1_FSTYPE" != "zfs" ]; then
9277                 run_acl_subtest 2561 || error "LU-2561 test failed"
9278         else
9279                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9280         fi
9281
9282         run_acl_subtest 4924 || error "LU-4924 test failed"
9283
9284         cd $SAVE_PWD
9285         umask $SAVE_UMASK
9286
9287         for num in $(seq $MDSCOUNT); do
9288                 if [ "${identity_old[$num]}" = 1 ]; then
9289                         switch_identity $num false || identity_old[$num]=$?
9290                 fi
9291         done
9292 }
9293 run_test 103a "acl test"
9294
9295 test_103b() {
9296         declare -a pids
9297         local U
9298
9299         for U in {0..511}; do
9300                 {
9301                 local O=$(printf "%04o" $U)
9302
9303                 umask $(printf "%04o" $((511 ^ $O)))
9304                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9305                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9306
9307                 (( $S == ($O & 0666) )) ||
9308                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9309
9310                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9311                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9312                 (( $S == ($O & 0666) )) ||
9313                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9314
9315                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9316                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9317                 (( $S == ($O & 0666) )) ||
9318                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9319                 rm -f $DIR/$tfile.[smp]$0
9320                 } &
9321                 local pid=$!
9322
9323                 # limit the concurrently running threads to 64. LU-11878
9324                 local idx=$((U % 64))
9325                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9326                 pids[idx]=$pid
9327         done
9328         wait
9329 }
9330 run_test 103b "umask lfs setstripe"
9331
9332 test_103c() {
9333         mkdir -p $DIR/$tdir
9334         cp -rp $DIR/$tdir $DIR/$tdir.bak
9335
9336         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9337                 error "$DIR/$tdir shouldn't contain default ACL"
9338         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9339                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9340         true
9341 }
9342 run_test 103c "'cp -rp' won't set empty acl"
9343
9344 test_104a() {
9345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9346
9347         touch $DIR/$tfile
9348         lfs df || error "lfs df failed"
9349         lfs df -ih || error "lfs df -ih failed"
9350         lfs df -h $DIR || error "lfs df -h $DIR failed"
9351         lfs df -i $DIR || error "lfs df -i $DIR failed"
9352         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9353         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9354
9355         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9356         lctl --device %$OSC deactivate
9357         lfs df || error "lfs df with deactivated OSC failed"
9358         lctl --device %$OSC activate
9359         # wait the osc back to normal
9360         wait_osc_import_ready client ost
9361
9362         lfs df || error "lfs df with reactivated OSC failed"
9363         rm -f $DIR/$tfile
9364 }
9365 run_test 104a "lfs df [-ih] [path] test ========================="
9366
9367 test_104b() {
9368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9369         [ $RUNAS_ID -eq $UID ] &&
9370                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9371
9372         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9373                         grep "Permission denied" | wc -l)))
9374         if [ $denied_cnt -ne 0 ]; then
9375                 error "lfs check servers test failed"
9376         fi
9377 }
9378 run_test 104b "$RUNAS lfs check servers test ===================="
9379
9380 test_105a() {
9381         # doesn't work on 2.4 kernels
9382         touch $DIR/$tfile
9383         if $(flock_is_enabled); then
9384                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9385         else
9386                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9387         fi
9388         rm -f $DIR/$tfile
9389 }
9390 run_test 105a "flock when mounted without -o flock test ========"
9391
9392 test_105b() {
9393         touch $DIR/$tfile
9394         if $(flock_is_enabled); then
9395                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9396         else
9397                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9398         fi
9399         rm -f $DIR/$tfile
9400 }
9401 run_test 105b "fcntl when mounted without -o flock test ========"
9402
9403 test_105c() {
9404         touch $DIR/$tfile
9405         if $(flock_is_enabled); then
9406                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9407         else
9408                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9409         fi
9410         rm -f $DIR/$tfile
9411 }
9412 run_test 105c "lockf when mounted without -o flock test"
9413
9414 test_105d() { # bug 15924
9415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9416
9417         test_mkdir $DIR/$tdir
9418         flock_is_enabled || skip_env "mount w/o flock enabled"
9419         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9420         $LCTL set_param fail_loc=0x80000315
9421         flocks_test 2 $DIR/$tdir
9422 }
9423 run_test 105d "flock race (should not freeze) ========"
9424
9425 test_105e() { # bug 22660 && 22040
9426         flock_is_enabled || skip_env "mount w/o flock enabled"
9427
9428         touch $DIR/$tfile
9429         flocks_test 3 $DIR/$tfile
9430 }
9431 run_test 105e "Two conflicting flocks from same process"
9432
9433 test_106() { #bug 10921
9434         test_mkdir $DIR/$tdir
9435         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9436         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9437 }
9438 run_test 106 "attempt exec of dir followed by chown of that dir"
9439
9440 test_107() {
9441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9442
9443         CDIR=`pwd`
9444         local file=core
9445
9446         cd $DIR
9447         rm -f $file
9448
9449         local save_pattern=$(sysctl -n kernel.core_pattern)
9450         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9451         sysctl -w kernel.core_pattern=$file
9452         sysctl -w kernel.core_uses_pid=0
9453
9454         ulimit -c unlimited
9455         sleep 60 &
9456         SLEEPPID=$!
9457
9458         sleep 1
9459
9460         kill -s 11 $SLEEPPID
9461         wait $SLEEPPID
9462         if [ -e $file ]; then
9463                 size=`stat -c%s $file`
9464                 [ $size -eq 0 ] && error "Fail to create core file $file"
9465         else
9466                 error "Fail to create core file $file"
9467         fi
9468         rm -f $file
9469         sysctl -w kernel.core_pattern=$save_pattern
9470         sysctl -w kernel.core_uses_pid=$save_uses_pid
9471         cd $CDIR
9472 }
9473 run_test 107 "Coredump on SIG"
9474
9475 test_110() {
9476         test_mkdir $DIR/$tdir
9477         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9478         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9479                 error "mkdir with 256 char should fail, but did not"
9480         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9481                 error "create with 255 char failed"
9482         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9483                 error "create with 256 char should fail, but did not"
9484
9485         ls -l $DIR/$tdir
9486         rm -rf $DIR/$tdir
9487 }
9488 run_test 110 "filename length checking"
9489
9490 #
9491 # Purpose: To verify dynamic thread (OSS) creation.
9492 #
9493 test_115() {
9494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9495         remote_ost_nodsh && skip "remote OST with nodsh"
9496
9497         # Lustre does not stop service threads once they are started.
9498         # Reset number of running threads to default.
9499         stopall
9500         setupall
9501
9502         local OSTIO_pre
9503         local save_params="$TMP/sanity-$TESTNAME.parameters"
9504
9505         # Get ll_ost_io count before I/O
9506         OSTIO_pre=$(do_facet ost1 \
9507                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9508         # Exit if lustre is not running (ll_ost_io not running).
9509         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9510
9511         echo "Starting with $OSTIO_pre threads"
9512         local thread_max=$((OSTIO_pre * 2))
9513         local rpc_in_flight=$((thread_max * 2))
9514         # Number of I/O Process proposed to be started.
9515         local nfiles
9516         local facets=$(get_facets OST)
9517
9518         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9519         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9520
9521         # Set in_flight to $rpc_in_flight
9522         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9523                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9524         nfiles=${rpc_in_flight}
9525         # Set ost thread_max to $thread_max
9526         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9527
9528         # 5 Minutes should be sufficient for max number of OSS
9529         # threads(thread_max) to be created.
9530         local timeout=300
9531
9532         # Start I/O.
9533         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9534         test_mkdir $DIR/$tdir
9535         for i in $(seq $nfiles); do
9536                 local file=$DIR/$tdir/${tfile}-$i
9537                 $LFS setstripe -c -1 -i 0 $file
9538                 ($WTL $file $timeout)&
9539         done
9540
9541         # I/O Started - Wait for thread_started to reach thread_max or report
9542         # error if thread_started is more than thread_max.
9543         echo "Waiting for thread_started to reach thread_max"
9544         local thread_started=0
9545         local end_time=$((SECONDS + timeout))
9546
9547         while [ $SECONDS -le $end_time ] ; do
9548                 echo -n "."
9549                 # Get ost i/o thread_started count.
9550                 thread_started=$(do_facet ost1 \
9551                         "$LCTL get_param \
9552                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9553                 # Break out if thread_started is equal/greater than thread_max
9554                 if [[ $thread_started -ge $thread_max ]]; then
9555                         echo ll_ost_io thread_started $thread_started, \
9556                                 equal/greater than thread_max $thread_max
9557                         break
9558                 fi
9559                 sleep 1
9560         done
9561
9562         # Cleanup - We have the numbers, Kill i/o jobs if running.
9563         jobcount=($(jobs -p))
9564         for i in $(seq 0 $((${#jobcount[@]}-1)))
9565         do
9566                 kill -9 ${jobcount[$i]}
9567                 if [ $? -ne 0 ] ; then
9568                         echo Warning: \
9569                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9570                 fi
9571         done
9572
9573         # Cleanup files left by WTL binary.
9574         for i in $(seq $nfiles); do
9575                 local file=$DIR/$tdir/${tfile}-$i
9576                 rm -rf $file
9577                 if [ $? -ne 0 ] ; then
9578                         echo "Warning: Failed to delete file $file"
9579                 fi
9580         done
9581
9582         restore_lustre_params <$save_params
9583         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9584
9585         # Error out if no new thread has started or Thread started is greater
9586         # than thread max.
9587         if [[ $thread_started -le $OSTIO_pre ||
9588                         $thread_started -gt $thread_max ]]; then
9589                 error "ll_ost_io: thread_started $thread_started" \
9590                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9591                       "No new thread started or thread started greater " \
9592                       "than thread_max."
9593         fi
9594 }
9595 run_test 115 "verify dynamic thread creation===================="
9596
9597 free_min_max () {
9598         wait_delete_completed
9599         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9600         echo "OST kbytes available: ${AVAIL[@]}"
9601         MAXV=${AVAIL[0]}
9602         MAXI=0
9603         MINV=${AVAIL[0]}
9604         MINI=0
9605         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9606                 #echo OST $i: ${AVAIL[i]}kb
9607                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9608                         MAXV=${AVAIL[i]}
9609                         MAXI=$i
9610                 fi
9611                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9612                         MINV=${AVAIL[i]}
9613                         MINI=$i
9614                 fi
9615         done
9616         echo "Min free space: OST $MINI: $MINV"
9617         echo "Max free space: OST $MAXI: $MAXV"
9618 }
9619
9620 test_116a() { # was previously test_116()
9621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9622         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9623         remote_mds_nodsh && skip "remote MDS with nodsh"
9624
9625         echo -n "Free space priority "
9626         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
9627                 head -n1
9628         declare -a AVAIL
9629         free_min_max
9630
9631         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9632         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9633         trap simple_cleanup_common EXIT
9634
9635         # Check if we need to generate uneven OSTs
9636         test_mkdir -p $DIR/$tdir/OST${MINI}
9637         local FILL=$((MINV / 4))
9638         local DIFF=$((MAXV - MINV))
9639         local DIFF2=$((DIFF * 100 / MINV))
9640
9641         local threshold=$(do_facet $SINGLEMDS \
9642                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9643         threshold=${threshold%%%}
9644         echo -n "Check for uneven OSTs: "
9645         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9646
9647         if [[ $DIFF2 -gt $threshold ]]; then
9648                 echo "ok"
9649                 echo "Don't need to fill OST$MINI"
9650         else
9651                 # generate uneven OSTs. Write 2% over the QOS threshold value
9652                 echo "no"
9653                 DIFF=$((threshold - DIFF2 + 2))
9654                 DIFF2=$((MINV * DIFF / 100))
9655                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9656                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9657                         error "setstripe failed"
9658                 DIFF=$((DIFF2 / 2048))
9659                 i=0
9660                 while [ $i -lt $DIFF ]; do
9661                         i=$((i + 1))
9662                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9663                                 bs=2M count=1 2>/dev/null
9664                         echo -n .
9665                 done
9666                 echo .
9667                 sync
9668                 sleep_maxage
9669                 free_min_max
9670         fi
9671
9672         DIFF=$((MAXV - MINV))
9673         DIFF2=$((DIFF * 100 / MINV))
9674         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9675         if [ $DIFF2 -gt $threshold ]; then
9676                 echo "ok"
9677         else
9678                 echo "failed - QOS mode won't be used"
9679                 simple_cleanup_common
9680                 skip "QOS imbalance criteria not met"
9681         fi
9682
9683         MINI1=$MINI
9684         MINV1=$MINV
9685         MAXI1=$MAXI
9686         MAXV1=$MAXV
9687
9688         # now fill using QOS
9689         $LFS setstripe -c 1 $DIR/$tdir
9690         FILL=$((FILL / 200))
9691         if [ $FILL -gt 600 ]; then
9692                 FILL=600
9693         fi
9694         echo "writing $FILL files to QOS-assigned OSTs"
9695         i=0
9696         while [ $i -lt $FILL ]; do
9697                 i=$((i + 1))
9698                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9699                         count=1 2>/dev/null
9700                 echo -n .
9701         done
9702         echo "wrote $i 200k files"
9703         sync
9704         sleep_maxage
9705
9706         echo "Note: free space may not be updated, so measurements might be off"
9707         free_min_max
9708         DIFF2=$((MAXV - MINV))
9709         echo "free space delta: orig $DIFF final $DIFF2"
9710         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9711         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9712         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9713         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9714         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9715         if [[ $DIFF -gt 0 ]]; then
9716                 FILL=$((DIFF2 * 100 / DIFF - 100))
9717                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9718         fi
9719
9720         # Figure out which files were written where
9721         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9722                awk '/'$MINI1': / {print $2; exit}')
9723         echo $UUID
9724         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9725         echo "$MINC files created on smaller OST $MINI1"
9726         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9727                awk '/'$MAXI1': / {print $2; exit}')
9728         echo $UUID
9729         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9730         echo "$MAXC files created on larger OST $MAXI1"
9731         if [[ $MINC -gt 0 ]]; then
9732                 FILL=$((MAXC * 100 / MINC - 100))
9733                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9734         fi
9735         [[ $MAXC -gt $MINC ]] ||
9736                 error_ignore LU-9 "stripe QOS didn't balance free space"
9737         simple_cleanup_common
9738 }
9739 run_test 116a "stripe QOS: free space balance ==================="
9740
9741 test_116b() { # LU-2093
9742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9743         remote_mds_nodsh && skip "remote MDS with nodsh"
9744
9745 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9746         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9747                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9748         [ -z "$old_rr" ] && skip "no QOS"
9749         do_facet $SINGLEMDS lctl set_param \
9750                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9751         mkdir -p $DIR/$tdir
9752         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9753         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9754         do_facet $SINGLEMDS lctl set_param fail_loc=0
9755         rm -rf $DIR/$tdir
9756         do_facet $SINGLEMDS lctl set_param \
9757                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9758 }
9759 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9760
9761 test_117() # bug 10891
9762 {
9763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9764
9765         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9766         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9767         lctl set_param fail_loc=0x21e
9768         > $DIR/$tfile || error "truncate failed"
9769         lctl set_param fail_loc=0
9770         echo "Truncate succeeded."
9771         rm -f $DIR/$tfile
9772 }
9773 run_test 117 "verify osd extend =========="
9774
9775 NO_SLOW_RESENDCOUNT=4
9776 export OLD_RESENDCOUNT=""
9777 set_resend_count () {
9778         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9779         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9780         lctl set_param -n $PROC_RESENDCOUNT $1
9781         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9782 }
9783
9784 # for reduce test_118* time (b=14842)
9785 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9786
9787 # Reset async IO behavior after error case
9788 reset_async() {
9789         FILE=$DIR/reset_async
9790
9791         # Ensure all OSCs are cleared
9792         $LFS setstripe -c -1 $FILE
9793         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9794         sync
9795         rm $FILE
9796 }
9797
9798 test_118a() #bug 11710
9799 {
9800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9801
9802         reset_async
9803
9804         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9805         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9806         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9807
9808         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9809                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9810                 return 1;
9811         fi
9812         rm -f $DIR/$tfile
9813 }
9814 run_test 118a "verify O_SYNC works =========="
9815
9816 test_118b()
9817 {
9818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9819         remote_ost_nodsh && skip "remote OST with nodsh"
9820
9821         reset_async
9822
9823         #define OBD_FAIL_SRV_ENOENT 0x217
9824         set_nodes_failloc "$(osts_nodes)" 0x217
9825         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9826         RC=$?
9827         set_nodes_failloc "$(osts_nodes)" 0
9828         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9829         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9830                     grep -c writeback)
9831
9832         if [[ $RC -eq 0 ]]; then
9833                 error "Must return error due to dropped pages, rc=$RC"
9834                 return 1;
9835         fi
9836
9837         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9838                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9839                 return 1;
9840         fi
9841
9842         echo "Dirty pages not leaked on ENOENT"
9843
9844         # Due to the above error the OSC will issue all RPCs syncronously
9845         # until a subsequent RPC completes successfully without error.
9846         $MULTIOP $DIR/$tfile Ow4096yc
9847         rm -f $DIR/$tfile
9848
9849         return 0
9850 }
9851 run_test 118b "Reclaim dirty pages on fatal error =========="
9852
9853 test_118c()
9854 {
9855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9856
9857         # for 118c, restore the original resend count, LU-1940
9858         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9859                                 set_resend_count $OLD_RESENDCOUNT
9860         remote_ost_nodsh && skip "remote OST with nodsh"
9861
9862         reset_async
9863
9864         #define OBD_FAIL_OST_EROFS               0x216
9865         set_nodes_failloc "$(osts_nodes)" 0x216
9866
9867         # multiop should block due to fsync until pages are written
9868         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9869         MULTIPID=$!
9870         sleep 1
9871
9872         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9873                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9874         fi
9875
9876         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9877                     grep -c writeback)
9878         if [[ $WRITEBACK -eq 0 ]]; then
9879                 error "No page in writeback, writeback=$WRITEBACK"
9880         fi
9881
9882         set_nodes_failloc "$(osts_nodes)" 0
9883         wait $MULTIPID
9884         RC=$?
9885         if [[ $RC -ne 0 ]]; then
9886                 error "Multiop fsync failed, rc=$RC"
9887         fi
9888
9889         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9890         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9891                     grep -c writeback)
9892         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9893                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9894         fi
9895
9896         rm -f $DIR/$tfile
9897         echo "Dirty pages flushed via fsync on EROFS"
9898         return 0
9899 }
9900 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9901
9902 # continue to use small resend count to reduce test_118* time (b=14842)
9903 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9904
9905 test_118d()
9906 {
9907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9908         remote_ost_nodsh && skip "remote OST with nodsh"
9909
9910         reset_async
9911
9912         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9913         set_nodes_failloc "$(osts_nodes)" 0x214
9914         # multiop should block due to fsync until pages are written
9915         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9916         MULTIPID=$!
9917         sleep 1
9918
9919         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9920                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9921         fi
9922
9923         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9924                     grep -c writeback)
9925         if [[ $WRITEBACK -eq 0 ]]; then
9926                 error "No page in writeback, writeback=$WRITEBACK"
9927         fi
9928
9929         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9930         set_nodes_failloc "$(osts_nodes)" 0
9931
9932         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9933         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9934                     grep -c writeback)
9935         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9936                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9937         fi
9938
9939         rm -f $DIR/$tfile
9940         echo "Dirty pages gaurenteed flushed via fsync"
9941         return 0
9942 }
9943 run_test 118d "Fsync validation inject a delay of the bulk =========="
9944
9945 test_118f() {
9946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9947
9948         reset_async
9949
9950         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9951         lctl set_param fail_loc=0x8000040a
9952
9953         # Should simulate EINVAL error which is fatal
9954         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9955         RC=$?
9956         if [[ $RC -eq 0 ]]; then
9957                 error "Must return error due to dropped pages, rc=$RC"
9958         fi
9959
9960         lctl set_param fail_loc=0x0
9961
9962         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9963         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9964         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9965                     grep -c writeback)
9966         if [[ $LOCKED -ne 0 ]]; then
9967                 error "Locked pages remain in cache, locked=$LOCKED"
9968         fi
9969
9970         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9971                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9972         fi
9973
9974         rm -f $DIR/$tfile
9975         echo "No pages locked after fsync"
9976
9977         reset_async
9978         return 0
9979 }
9980 run_test 118f "Simulate unrecoverable OSC side error =========="
9981
9982 test_118g() {
9983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9984
9985         reset_async
9986
9987         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9988         lctl set_param fail_loc=0x406
9989
9990         # simulate local -ENOMEM
9991         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9992         RC=$?
9993
9994         lctl set_param fail_loc=0
9995         if [[ $RC -eq 0 ]]; then
9996                 error "Must return error due to dropped pages, rc=$RC"
9997         fi
9998
9999         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10000         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10001         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10002                         grep -c writeback)
10003         if [[ $LOCKED -ne 0 ]]; then
10004                 error "Locked pages remain in cache, locked=$LOCKED"
10005         fi
10006
10007         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10008                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10009         fi
10010
10011         rm -f $DIR/$tfile
10012         echo "No pages locked after fsync"
10013
10014         reset_async
10015         return 0
10016 }
10017 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10018
10019 test_118h() {
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         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10028         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10029         RC=$?
10030
10031         set_nodes_failloc "$(osts_nodes)" 0
10032         if [[ $RC -eq 0 ]]; then
10033                 error "Must return error due to dropped pages, rc=$RC"
10034         fi
10035
10036         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10037         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10038         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10039                     grep -c writeback)
10040         if [[ $LOCKED -ne 0 ]]; then
10041                 error "Locked pages remain in cache, locked=$LOCKED"
10042         fi
10043
10044         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10045                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10046         fi
10047
10048         rm -f $DIR/$tfile
10049         echo "No pages locked after fsync"
10050
10051         return 0
10052 }
10053 run_test 118h "Verify timeout in handling recoverables errors  =========="
10054
10055 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10056
10057 test_118i() {
10058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10059         remote_ost_nodsh && skip "remote OST with nodsh"
10060
10061         reset_async
10062
10063         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10064         set_nodes_failloc "$(osts_nodes)" 0x20e
10065
10066         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10067         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10068         PID=$!
10069         sleep 5
10070         set_nodes_failloc "$(osts_nodes)" 0
10071
10072         wait $PID
10073         RC=$?
10074         if [[ $RC -ne 0 ]]; then
10075                 error "got error, but should be not, rc=$RC"
10076         fi
10077
10078         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10079         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10080         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10081         if [[ $LOCKED -ne 0 ]]; then
10082                 error "Locked pages remain in cache, locked=$LOCKED"
10083         fi
10084
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 118i "Fix error before timeout in recoverable error  =========="
10095
10096 [ "$SLOW" = "no" ] && set_resend_count 4
10097
10098 test_118j() {
10099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10100         remote_ost_nodsh && skip "remote OST with nodsh"
10101
10102         reset_async
10103
10104         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10105         set_nodes_failloc "$(osts_nodes)" 0x220
10106
10107         # return -EIO from OST
10108         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10109         RC=$?
10110         set_nodes_failloc "$(osts_nodes)" 0x0
10111         if [[ $RC -eq 0 ]]; then
10112                 error "Must return error due to dropped pages, rc=$RC"
10113         fi
10114
10115         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10116         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10117         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10118         if [[ $LOCKED -ne 0 ]]; then
10119                 error "Locked pages remain in cache, locked=$LOCKED"
10120         fi
10121
10122         # in recoverable error on OST we want resend and stay until it finished
10123         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10124                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10125         fi
10126
10127         rm -f $DIR/$tfile
10128         echo "No pages locked after fsync"
10129
10130         return 0
10131 }
10132 run_test 118j "Simulate unrecoverable OST side error =========="
10133
10134 test_118k()
10135 {
10136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10137         remote_ost_nodsh && skip "remote OSTs with nodsh"
10138
10139         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10140         set_nodes_failloc "$(osts_nodes)" 0x20e
10141         test_mkdir $DIR/$tdir
10142
10143         for ((i=0;i<10;i++)); do
10144                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10145                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10146                 SLEEPPID=$!
10147                 sleep 0.500s
10148                 kill $SLEEPPID
10149                 wait $SLEEPPID
10150         done
10151
10152         set_nodes_failloc "$(osts_nodes)" 0
10153         rm -rf $DIR/$tdir
10154 }
10155 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10156
10157 test_118l() # LU-646
10158 {
10159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10160
10161         test_mkdir $DIR/$tdir
10162         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10163         rm -rf $DIR/$tdir
10164 }
10165 run_test 118l "fsync dir"
10166
10167 test_118m() # LU-3066
10168 {
10169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10170
10171         test_mkdir $DIR/$tdir
10172         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10173         rm -rf $DIR/$tdir
10174 }
10175 run_test 118m "fdatasync dir ========="
10176
10177 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10178
10179 test_118n()
10180 {
10181         local begin
10182         local end
10183
10184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10185         remote_ost_nodsh && skip "remote OSTs with nodsh"
10186
10187         # Sleep to avoid a cached response.
10188         #define OBD_STATFS_CACHE_SECONDS 1
10189         sleep 2
10190
10191         # Inject a 10 second delay in the OST_STATFS handler.
10192         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10193         set_nodes_failloc "$(osts_nodes)" 0x242
10194
10195         begin=$SECONDS
10196         stat --file-system $MOUNT > /dev/null
10197         end=$SECONDS
10198
10199         set_nodes_failloc "$(osts_nodes)" 0
10200
10201         if ((end - begin > 20)); then
10202             error "statfs took $((end - begin)) seconds, expected 10"
10203         fi
10204 }
10205 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10206
10207 test_119a() # bug 11737
10208 {
10209         BSIZE=$((512 * 1024))
10210         directio write $DIR/$tfile 0 1 $BSIZE
10211         # We ask to read two blocks, which is more than a file size.
10212         # directio will indicate an error when requested and actual
10213         # sizes aren't equeal (a normal situation in this case) and
10214         # print actual read amount.
10215         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10216         if [ "$NOB" != "$BSIZE" ]; then
10217                 error "read $NOB bytes instead of $BSIZE"
10218         fi
10219         rm -f $DIR/$tfile
10220 }
10221 run_test 119a "Short directIO read must return actual read amount"
10222
10223 test_119b() # bug 11737
10224 {
10225         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10226
10227         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10228         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10229         sync
10230         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10231                 error "direct read failed"
10232         rm -f $DIR/$tfile
10233 }
10234 run_test 119b "Sparse directIO read must return actual read amount"
10235
10236 test_119c() # bug 13099
10237 {
10238         BSIZE=1048576
10239         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10240         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10241         rm -f $DIR/$tfile
10242 }
10243 run_test 119c "Testing for direct read hitting hole"
10244
10245 test_119d() # bug 15950
10246 {
10247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10248
10249         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10250         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10251         BSIZE=1048576
10252         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10253         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10254         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10255         lctl set_param fail_loc=0x40d
10256         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10257         pid_dio=$!
10258         sleep 1
10259         cat $DIR/$tfile > /dev/null &
10260         lctl set_param fail_loc=0
10261         pid_reads=$!
10262         wait $pid_dio
10263         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10264         sleep 2
10265         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10266         error "the read rpcs have not completed in 2s"
10267         rm -f $DIR/$tfile
10268         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10269 }
10270 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10271
10272 test_120a() {
10273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10274         remote_mds_nodsh && skip "remote MDS with nodsh"
10275         test_mkdir -i0 -c1 $DIR/$tdir
10276         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10277                 skip_env "no early lock cancel on server"
10278
10279         lru_resize_disable mdc
10280         lru_resize_disable osc
10281         cancel_lru_locks mdc
10282         # asynchronous object destroy at MDT could cause bl ast to client
10283         cancel_lru_locks osc
10284
10285         stat $DIR/$tdir > /dev/null
10286         can1=$(do_facet mds1 \
10287                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10288                awk '/ldlm_cancel/ {print $2}')
10289         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10290                awk '/ldlm_bl_callback/ {print $2}')
10291         test_mkdir -i0 -c1 $DIR/$tdir/d1
10292         can2=$(do_facet mds1 \
10293                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10294                awk '/ldlm_cancel/ {print $2}')
10295         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10296                awk '/ldlm_bl_callback/ {print $2}')
10297         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10298         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10299         lru_resize_enable mdc
10300         lru_resize_enable osc
10301 }
10302 run_test 120a "Early Lock Cancel: mkdir test"
10303
10304 test_120b() {
10305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10306         remote_mds_nodsh && skip "remote MDS with nodsh"
10307         test_mkdir $DIR/$tdir
10308         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10309                 skip_env "no early lock cancel on server"
10310
10311         lru_resize_disable mdc
10312         lru_resize_disable osc
10313         cancel_lru_locks mdc
10314         stat $DIR/$tdir > /dev/null
10315         can1=$(do_facet $SINGLEMDS \
10316                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10317                awk '/ldlm_cancel/ {print $2}')
10318         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10319                awk '/ldlm_bl_callback/ {print $2}')
10320         touch $DIR/$tdir/f1
10321         can2=$(do_facet $SINGLEMDS \
10322                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10323                awk '/ldlm_cancel/ {print $2}')
10324         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10325                awk '/ldlm_bl_callback/ {print $2}')
10326         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10327         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10328         lru_resize_enable mdc
10329         lru_resize_enable osc
10330 }
10331 run_test 120b "Early Lock Cancel: create test"
10332
10333 test_120c() {
10334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10335         remote_mds_nodsh && skip "remote MDS with nodsh"
10336         test_mkdir -i0 -c1 $DIR/$tdir
10337         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10338                 skip "no early lock cancel on server"
10339
10340         lru_resize_disable mdc
10341         lru_resize_disable osc
10342         test_mkdir -i0 -c1 $DIR/$tdir/d1
10343         test_mkdir -i0 -c1 $DIR/$tdir/d2
10344         touch $DIR/$tdir/d1/f1
10345         cancel_lru_locks mdc
10346         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10347         can1=$(do_facet mds1 \
10348                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10349                awk '/ldlm_cancel/ {print $2}')
10350         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10351                awk '/ldlm_bl_callback/ {print $2}')
10352         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10353         can2=$(do_facet mds1 \
10354                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10355                awk '/ldlm_cancel/ {print $2}')
10356         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10357                awk '/ldlm_bl_callback/ {print $2}')
10358         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10359         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10360         lru_resize_enable mdc
10361         lru_resize_enable osc
10362 }
10363 run_test 120c "Early Lock Cancel: link test"
10364
10365 test_120d() {
10366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10367         remote_mds_nodsh && skip "remote MDS with nodsh"
10368         test_mkdir -i0 -c1 $DIR/$tdir
10369         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10370                 skip_env "no early lock cancel on server"
10371
10372         lru_resize_disable mdc
10373         lru_resize_disable osc
10374         touch $DIR/$tdir
10375         cancel_lru_locks mdc
10376         stat $DIR/$tdir > /dev/null
10377         can1=$(do_facet mds1 \
10378                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10379                awk '/ldlm_cancel/ {print $2}')
10380         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10381                awk '/ldlm_bl_callback/ {print $2}')
10382         chmod a+x $DIR/$tdir
10383         can2=$(do_facet mds1 \
10384                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10385                awk '/ldlm_cancel/ {print $2}')
10386         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10387                awk '/ldlm_bl_callback/ {print $2}')
10388         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10389         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10390         lru_resize_enable mdc
10391         lru_resize_enable osc
10392 }
10393 run_test 120d "Early Lock Cancel: setattr test"
10394
10395 test_120e() {
10396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10397         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10398                 skip_env "no early lock cancel on server"
10399         remote_mds_nodsh && skip "remote MDS with nodsh"
10400
10401         local dlmtrace_set=false
10402
10403         test_mkdir -i0 -c1 $DIR/$tdir
10404         lru_resize_disable mdc
10405         lru_resize_disable osc
10406         ! $LCTL get_param debug | grep -q dlmtrace &&
10407                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10408         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10409         cancel_lru_locks mdc
10410         cancel_lru_locks osc
10411         dd if=$DIR/$tdir/f1 of=/dev/null
10412         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10413         # XXX client can not do early lock cancel of OST lock
10414         # during unlink (LU-4206), so cancel osc lock now.
10415         sleep 2
10416         cancel_lru_locks osc
10417         can1=$(do_facet mds1 \
10418                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10419                awk '/ldlm_cancel/ {print $2}')
10420         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10421                awk '/ldlm_bl_callback/ {print $2}')
10422         unlink $DIR/$tdir/f1
10423         sleep 5
10424         can2=$(do_facet mds1 \
10425                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10426                awk '/ldlm_cancel/ {print $2}')
10427         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10428                awk '/ldlm_bl_callback/ {print $2}')
10429         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10430                 $LCTL dk $TMP/cancel.debug.txt
10431         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10432                 $LCTL dk $TMP/blocking.debug.txt
10433         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10434         lru_resize_enable mdc
10435         lru_resize_enable osc
10436 }
10437 run_test 120e "Early Lock Cancel: unlink test"
10438
10439 test_120f() {
10440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10441         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10442                 skip_env "no early lock cancel on server"
10443         remote_mds_nodsh && skip "remote MDS with nodsh"
10444
10445         test_mkdir -i0 -c1 $DIR/$tdir
10446         lru_resize_disable mdc
10447         lru_resize_disable osc
10448         test_mkdir -i0 -c1 $DIR/$tdir/d1
10449         test_mkdir -i0 -c1 $DIR/$tdir/d2
10450         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10451         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10452         cancel_lru_locks mdc
10453         cancel_lru_locks osc
10454         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10455         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10456         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10457         # XXX client can not do early lock cancel of OST lock
10458         # during rename (LU-4206), so cancel osc lock now.
10459         sleep 2
10460         cancel_lru_locks osc
10461         can1=$(do_facet mds1 \
10462                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10463                awk '/ldlm_cancel/ {print $2}')
10464         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10465                awk '/ldlm_bl_callback/ {print $2}')
10466         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10467         sleep 5
10468         can2=$(do_facet mds1 \
10469                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10470                awk '/ldlm_cancel/ {print $2}')
10471         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10472                awk '/ldlm_bl_callback/ {print $2}')
10473         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10474         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10475         lru_resize_enable mdc
10476         lru_resize_enable osc
10477 }
10478 run_test 120f "Early Lock Cancel: rename test"
10479
10480 test_120g() {
10481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10482         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10483                 skip_env "no early lock cancel on server"
10484         remote_mds_nodsh && skip "remote MDS with nodsh"
10485
10486         lru_resize_disable mdc
10487         lru_resize_disable osc
10488         count=10000
10489         echo create $count files
10490         test_mkdir $DIR/$tdir
10491         cancel_lru_locks mdc
10492         cancel_lru_locks osc
10493         t0=$(date +%s)
10494
10495         can0=$(do_facet $SINGLEMDS \
10496                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10497                awk '/ldlm_cancel/ {print $2}')
10498         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10499                awk '/ldlm_bl_callback/ {print $2}')
10500         createmany -o $DIR/$tdir/f $count
10501         sync
10502         can1=$(do_facet $SINGLEMDS \
10503                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10504                awk '/ldlm_cancel/ {print $2}')
10505         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10506                awk '/ldlm_bl_callback/ {print $2}')
10507         t1=$(date +%s)
10508         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10509         echo rm $count files
10510         rm -r $DIR/$tdir
10511         sync
10512         can2=$(do_facet $SINGLEMDS \
10513                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10514                awk '/ldlm_cancel/ {print $2}')
10515         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10516                awk '/ldlm_bl_callback/ {print $2}')
10517         t2=$(date +%s)
10518         echo total: $count removes in $((t2-t1))
10519         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10520         sleep 2
10521         # wait for commitment of removal
10522         lru_resize_enable mdc
10523         lru_resize_enable osc
10524 }
10525 run_test 120g "Early Lock Cancel: performance test"
10526
10527 test_121() { #bug #10589
10528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10529
10530         rm -rf $DIR/$tfile
10531         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10532 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10533         lctl set_param fail_loc=0x310
10534         cancel_lru_locks osc > /dev/null
10535         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10536         lctl set_param fail_loc=0
10537         [[ $reads -eq $writes ]] ||
10538                 error "read $reads blocks, must be $writes blocks"
10539 }
10540 run_test 121 "read cancel race ========="
10541
10542 test_123a() { # was test 123, statahead(bug 11401)
10543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10544
10545         SLOWOK=0
10546         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10547                 log "testing UP system. Performance may be lower than expected."
10548                 SLOWOK=1
10549         fi
10550
10551         rm -rf $DIR/$tdir
10552         test_mkdir $DIR/$tdir
10553         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10554         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10555         MULT=10
10556         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10557                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10558
10559                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10560                 lctl set_param -n llite.*.statahead_max 0
10561                 lctl get_param llite.*.statahead_max
10562                 cancel_lru_locks mdc
10563                 cancel_lru_locks osc
10564                 stime=`date +%s`
10565                 time ls -l $DIR/$tdir | wc -l
10566                 etime=`date +%s`
10567                 delta=$((etime - stime))
10568                 log "ls $i files without statahead: $delta sec"
10569                 lctl set_param llite.*.statahead_max=$max
10570
10571                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10572                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10573                 cancel_lru_locks mdc
10574                 cancel_lru_locks osc
10575                 stime=`date +%s`
10576                 time ls -l $DIR/$tdir | wc -l
10577                 etime=`date +%s`
10578                 delta_sa=$((etime - stime))
10579                 log "ls $i files with statahead: $delta_sa sec"
10580                 lctl get_param -n llite.*.statahead_stats
10581                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10582
10583                 [[ $swrong -lt $ewrong ]] &&
10584                         log "statahead was stopped, maybe too many locks held!"
10585                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10586
10587                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10588                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10589                     lctl set_param -n llite.*.statahead_max 0
10590                     lctl get_param llite.*.statahead_max
10591                     cancel_lru_locks mdc
10592                     cancel_lru_locks osc
10593                     stime=`date +%s`
10594                     time ls -l $DIR/$tdir | wc -l
10595                     etime=`date +%s`
10596                     delta=$((etime - stime))
10597                     log "ls $i files again without statahead: $delta sec"
10598                     lctl set_param llite.*.statahead_max=$max
10599                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10600                         if [  $SLOWOK -eq 0 ]; then
10601                                 error "ls $i files is slower with statahead!"
10602                         else
10603                                 log "ls $i files is slower with statahead!"
10604                         fi
10605                         break
10606                     fi
10607                 fi
10608
10609                 [ $delta -gt 20 ] && break
10610                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10611                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10612         done
10613         log "ls done"
10614
10615         stime=`date +%s`
10616         rm -r $DIR/$tdir
10617         sync
10618         etime=`date +%s`
10619         delta=$((etime - stime))
10620         log "rm -r $DIR/$tdir/: $delta seconds"
10621         log "rm done"
10622         lctl get_param -n llite.*.statahead_stats
10623 }
10624 run_test 123a "verify statahead work"
10625
10626 test_123b () { # statahead(bug 15027)
10627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10628
10629         test_mkdir $DIR/$tdir
10630         createmany -o $DIR/$tdir/$tfile-%d 1000
10631
10632         cancel_lru_locks mdc
10633         cancel_lru_locks osc
10634
10635 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10636         lctl set_param fail_loc=0x80000803
10637         ls -lR $DIR/$tdir > /dev/null
10638         log "ls done"
10639         lctl set_param fail_loc=0x0
10640         lctl get_param -n llite.*.statahead_stats
10641         rm -r $DIR/$tdir
10642         sync
10643
10644 }
10645 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10646
10647 test_124a() {
10648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10649         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10650                 skip_env "no lru resize on server"
10651
10652         local NR=2000
10653
10654         test_mkdir $DIR/$tdir
10655
10656         log "create $NR files at $DIR/$tdir"
10657         createmany -o $DIR/$tdir/f $NR ||
10658                 error "failed to create $NR files in $DIR/$tdir"
10659
10660         cancel_lru_locks mdc
10661         ls -l $DIR/$tdir > /dev/null
10662
10663         local NSDIR=""
10664         local LRU_SIZE=0
10665         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10666                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10667                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10668                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10669                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10670                         log "NSDIR=$NSDIR"
10671                         log "NS=$(basename $NSDIR)"
10672                         break
10673                 fi
10674         done
10675
10676         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10677                 skip "Not enough cached locks created!"
10678         fi
10679         log "LRU=$LRU_SIZE"
10680
10681         local SLEEP=30
10682
10683         # We know that lru resize allows one client to hold $LIMIT locks
10684         # for 10h. After that locks begin to be killed by client.
10685         local MAX_HRS=10
10686         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10687         log "LIMIT=$LIMIT"
10688         if [ $LIMIT -lt $LRU_SIZE ]; then
10689                 skip "Limit is too small $LIMIT"
10690         fi
10691
10692         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10693         # killing locks. Some time was spent for creating locks. This means
10694         # that up to the moment of sleep finish we must have killed some of
10695         # them (10-100 locks). This depends on how fast ther were created.
10696         # Many of them were touched in almost the same moment and thus will
10697         # be killed in groups.
10698         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10699
10700         # Use $LRU_SIZE_B here to take into account real number of locks
10701         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10702         local LRU_SIZE_B=$LRU_SIZE
10703         log "LVF=$LVF"
10704         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10705         log "OLD_LVF=$OLD_LVF"
10706         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10707
10708         # Let's make sure that we really have some margin. Client checks
10709         # cached locks every 10 sec.
10710         SLEEP=$((SLEEP+20))
10711         log "Sleep ${SLEEP} sec"
10712         local SEC=0
10713         while ((SEC<$SLEEP)); do
10714                 echo -n "..."
10715                 sleep 5
10716                 SEC=$((SEC+5))
10717                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10718                 echo -n "$LRU_SIZE"
10719         done
10720         echo ""
10721         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10722         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10723
10724         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10725                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10726                 unlinkmany $DIR/$tdir/f $NR
10727                 return
10728         }
10729
10730         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10731         log "unlink $NR files at $DIR/$tdir"
10732         unlinkmany $DIR/$tdir/f $NR
10733 }
10734 run_test 124a "lru resize ======================================="
10735
10736 get_max_pool_limit()
10737 {
10738         local limit=$($LCTL get_param \
10739                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10740         local max=0
10741         for l in $limit; do
10742                 if [[ $l -gt $max ]]; then
10743                         max=$l
10744                 fi
10745         done
10746         echo $max
10747 }
10748
10749 test_124b() {
10750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10751         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10752                 skip_env "no lru resize on server"
10753
10754         LIMIT=$(get_max_pool_limit)
10755
10756         NR=$(($(default_lru_size)*20))
10757         if [[ $NR -gt $LIMIT ]]; then
10758                 log "Limit lock number by $LIMIT locks"
10759                 NR=$LIMIT
10760         fi
10761
10762         IFree=$(mdsrate_inodes_available)
10763         if [ $IFree -lt $NR ]; then
10764                 log "Limit lock number by $IFree inodes"
10765                 NR=$IFree
10766         fi
10767
10768         lru_resize_disable mdc
10769         test_mkdir -p $DIR/$tdir/disable_lru_resize
10770
10771         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10772         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10773         cancel_lru_locks mdc
10774         stime=`date +%s`
10775         PID=""
10776         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10777         PID="$PID $!"
10778         sleep 2
10779         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10780         PID="$PID $!"
10781         sleep 2
10782         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10783         PID="$PID $!"
10784         wait $PID
10785         etime=`date +%s`
10786         nolruresize_delta=$((etime-stime))
10787         log "ls -la time: $nolruresize_delta seconds"
10788         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10789         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10790
10791         lru_resize_enable mdc
10792         test_mkdir -p $DIR/$tdir/enable_lru_resize
10793
10794         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10795         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10796         cancel_lru_locks mdc
10797         stime=`date +%s`
10798         PID=""
10799         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10800         PID="$PID $!"
10801         sleep 2
10802         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10803         PID="$PID $!"
10804         sleep 2
10805         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10806         PID="$PID $!"
10807         wait $PID
10808         etime=`date +%s`
10809         lruresize_delta=$((etime-stime))
10810         log "ls -la time: $lruresize_delta seconds"
10811         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10812
10813         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10814                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10815         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10816                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10817         else
10818                 log "lru resize performs the same with no lru resize"
10819         fi
10820         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10821 }
10822 run_test 124b "lru resize (performance test) ======================="
10823
10824 test_124c() {
10825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10826         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10827                 skip_env "no lru resize on server"
10828
10829         # cache ununsed locks on client
10830         local nr=100
10831         cancel_lru_locks mdc
10832         test_mkdir $DIR/$tdir
10833         createmany -o $DIR/$tdir/f $nr ||
10834                 error "failed to create $nr files in $DIR/$tdir"
10835         ls -l $DIR/$tdir > /dev/null
10836
10837         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10838         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10839         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10840         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10841         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10842
10843         # set lru_max_age to 1 sec
10844         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10845         echo "sleep $((recalc_p * 2)) seconds..."
10846         sleep $((recalc_p * 2))
10847
10848         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10849         # restore lru_max_age
10850         $LCTL set_param -n $nsdir.lru_max_age $max_age
10851         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10852         unlinkmany $DIR/$tdir/f $nr
10853 }
10854 run_test 124c "LRUR cancel very aged locks"
10855
10856 test_124d() {
10857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10858         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10859                 skip_env "no lru resize on server"
10860
10861         # cache ununsed locks on client
10862         local nr=100
10863
10864         lru_resize_disable mdc
10865         stack_trap "lru_resize_enable mdc" EXIT
10866
10867         cancel_lru_locks mdc
10868
10869         # asynchronous object destroy at MDT could cause bl ast to client
10870         test_mkdir $DIR/$tdir
10871         createmany -o $DIR/$tdir/f $nr ||
10872                 error "failed to create $nr files in $DIR/$tdir"
10873         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
10874
10875         ls -l $DIR/$tdir > /dev/null
10876
10877         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10878         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10879         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10880         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10881
10882         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10883
10884         # set lru_max_age to 1 sec
10885         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10886         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
10887
10888         echo "sleep $((recalc_p * 2)) seconds..."
10889         sleep $((recalc_p * 2))
10890
10891         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10892
10893         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10894 }
10895 run_test 124d "cancel very aged locks if lru-resize diasbaled"
10896
10897 test_125() { # 13358
10898         $LCTL get_param -n llite.*.client_type | grep -q local ||
10899                 skip "must run as local client"
10900         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10901                 skip_env "must have acl enabled"
10902         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10903
10904         test_mkdir $DIR/$tdir
10905         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10906         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10907         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10908 }
10909 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10910
10911 test_126() { # bug 12829/13455
10912         $GSS && skip_env "must run as gss disabled"
10913         $LCTL get_param -n llite.*.client_type | grep -q local ||
10914                 skip "must run as local client"
10915         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10916
10917         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10918         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10919         rm -f $DIR/$tfile
10920         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10921 }
10922 run_test 126 "check that the fsgid provided by the client is taken into account"
10923
10924 test_127a() { # bug 15521
10925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10926
10927         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10928         $LCTL set_param osc.*.stats=0
10929         FSIZE=$((2048 * 1024))
10930         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10931         cancel_lru_locks osc
10932         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10933
10934         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10935         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10936                 echo "got $COUNT $NAME"
10937                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10938                 eval $NAME=$COUNT || error "Wrong proc format"
10939
10940                 case $NAME in
10941                         read_bytes|write_bytes)
10942                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10943                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10944                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10945                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10946                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10947                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10948                                 error "sumsquare is too small: $SUMSQ"
10949                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10950                                 error "sumsquare is too big: $SUMSQ"
10951                         ;;
10952                         *) ;;
10953                 esac
10954         done < $DIR/${tfile}.tmp
10955
10956         #check that we actually got some stats
10957         [ "$read_bytes" ] || error "Missing read_bytes stats"
10958         [ "$write_bytes" ] || error "Missing write_bytes stats"
10959         [ "$read_bytes" != 0 ] || error "no read done"
10960         [ "$write_bytes" != 0 ] || error "no write done"
10961 }
10962 run_test 127a "verify the client stats are sane"
10963
10964 test_127b() { # bug LU-333
10965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10966         local name count samp unit min max sum sumsq
10967
10968         $LCTL set_param llite.*.stats=0
10969
10970         # perform 2 reads and writes so MAX is different from SUM.
10971         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10972         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10973         cancel_lru_locks osc
10974         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10975         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10976
10977         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10978         while read name count samp unit min max sum sumsq; do
10979                 echo "got $count $name"
10980                 eval $name=$count || error "Wrong proc format"
10981
10982                 case $name in
10983                 read_bytes)
10984                         [ $count -ne 2 ] && error "count is not 2: $count"
10985                         [ $min -ne $PAGE_SIZE ] &&
10986                                 error "min is not $PAGE_SIZE: $min"
10987                         [ $max -ne $PAGE_SIZE ] &&
10988                                 error "max is incorrect: $max"
10989                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10990                                 error "sum is wrong: $sum"
10991                         ;;
10992                 write_bytes)
10993                         [ $count -ne 2 ] && error "count is not 2: $count"
10994                         [ $min -ne $PAGE_SIZE ] &&
10995                                 error "min is not $PAGE_SIZE: $min"
10996                         [ $max -ne $PAGE_SIZE ] &&
10997                                 error "max is incorrect: $max"
10998                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10999                                 error "sum is wrong: $sum"
11000                         ;;
11001                 *) ;;
11002                 esac
11003         done < $TMP/$tfile.tmp
11004
11005         #check that we actually got some stats
11006         [ "$read_bytes" ] || error "Missing read_bytes stats"
11007         [ "$write_bytes" ] || error "Missing write_bytes stats"
11008         [ "$read_bytes" != 0 ] || error "no read done"
11009         [ "$write_bytes" != 0 ] || error "no write done"
11010
11011         rm -f $TMP/${tfile}.tmp
11012 }
11013 run_test 127b "verify the llite client stats are sane"
11014
11015 test_128() { # bug 15212
11016         touch $DIR/$tfile
11017         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11018                 find $DIR/$tfile
11019                 find $DIR/$tfile
11020         EOF
11021
11022         result=$(grep error $TMP/$tfile.log)
11023         rm -f $DIR/$tfile $TMP/$tfile.log
11024         [ -z "$result" ] ||
11025                 error "consecutive find's under interactive lfs failed"
11026 }
11027 run_test 128 "interactive lfs for 2 consecutive find's"
11028
11029 set_dir_limits () {
11030         local mntdev
11031         local canondev
11032         local node
11033
11034         local ldproc=/proc/fs/ldiskfs
11035         local facets=$(get_facets MDS)
11036
11037         for facet in ${facets//,/ }; do
11038                 canondev=$(ldiskfs_canon \
11039                            *.$(convert_facet2label $facet).mntdev $facet)
11040                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11041                         ldproc=/sys/fs/ldiskfs
11042                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11043                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11044         done
11045 }
11046
11047 check_mds_dmesg() {
11048         local facets=$(get_facets MDS)
11049         for facet in ${facets//,/ }; do
11050                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11051         done
11052         return 1
11053 }
11054
11055 test_129() {
11056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11057         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11058                 skip "Need MDS version with at least 2.5.56"
11059         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11060                 skip_env "ldiskfs only test"
11061         fi
11062         remote_mds_nodsh && skip "remote MDS with nodsh"
11063
11064         local ENOSPC=28
11065         local EFBIG=27
11066         local has_warning=false
11067
11068         rm -rf $DIR/$tdir
11069         mkdir -p $DIR/$tdir
11070
11071         # block size of mds1
11072         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11073         set_dir_limits $maxsize $maxsize
11074         local dirsize=$(stat -c%s "$DIR/$tdir")
11075         local nfiles=0
11076         while [[ $dirsize -le $maxsize ]]; do
11077                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11078                 rc=$?
11079                 if ! $has_warning; then
11080                         check_mds_dmesg '"is approaching"' && has_warning=true
11081                 fi
11082                 # check two errors:
11083                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11084                 # EFBIG for previous versions included in ldiskfs series
11085                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11086                         set_dir_limits 0 0
11087                         echo "return code $rc received as expected"
11088
11089                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11090                                 error_exit "create failed w/o dir size limit"
11091
11092                         check_mds_dmesg '"has reached"' ||
11093                                 error_exit "reached message should be output"
11094
11095                         [ $has_warning = "false" ] &&
11096                                 error_exit "warning message should be output"
11097
11098                         dirsize=$(stat -c%s "$DIR/$tdir")
11099
11100                         [[ $dirsize -ge $maxsize ]] && return 0
11101                         error_exit "current dir size $dirsize, " \
11102                                    "previous limit $maxsize"
11103                 elif [ $rc -ne 0 ]; then
11104                         set_dir_limits 0 0
11105                         error_exit "return $rc received instead of expected " \
11106                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11107                 fi
11108                 nfiles=$((nfiles + 1))
11109                 dirsize=$(stat -c%s "$DIR/$tdir")
11110         done
11111
11112         set_dir_limits 0 0
11113         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11114 }
11115 run_test 129 "test directory size limit ========================"
11116
11117 OLDIFS="$IFS"
11118 cleanup_130() {
11119         trap 0
11120         IFS="$OLDIFS"
11121 }
11122
11123 test_130a() {
11124         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11125         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11126
11127         trap cleanup_130 EXIT RETURN
11128
11129         local fm_file=$DIR/$tfile
11130         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11131         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11132                 error "dd failed for $fm_file"
11133
11134         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11135         filefrag -ves $fm_file
11136         RC=$?
11137         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11138                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11139         [ $RC != 0 ] && error "filefrag $fm_file failed"
11140
11141         filefrag_op=$(filefrag -ve -k $fm_file |
11142                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11143         lun=$($LFS getstripe -i $fm_file)
11144
11145         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11146         IFS=$'\n'
11147         tot_len=0
11148         for line in $filefrag_op
11149         do
11150                 frag_lun=`echo $line | cut -d: -f5`
11151                 ext_len=`echo $line | cut -d: -f4`
11152                 if (( $frag_lun != $lun )); then
11153                         cleanup_130
11154                         error "FIEMAP on 1-stripe file($fm_file) failed"
11155                         return
11156                 fi
11157                 (( tot_len += ext_len ))
11158         done
11159
11160         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11161                 cleanup_130
11162                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11163                 return
11164         fi
11165
11166         cleanup_130
11167
11168         echo "FIEMAP on single striped file succeeded"
11169 }
11170 run_test 130a "FIEMAP (1-stripe file)"
11171
11172 test_130b() {
11173         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11174
11175         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11176         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11177
11178         trap cleanup_130 EXIT RETURN
11179
11180         local fm_file=$DIR/$tfile
11181         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11182                         error "setstripe on $fm_file"
11183         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11184                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11185
11186         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11187                 error "dd failed on $fm_file"
11188
11189         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11190         filefrag_op=$(filefrag -ve -k $fm_file |
11191                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11192
11193         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11194                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11195
11196         IFS=$'\n'
11197         tot_len=0
11198         num_luns=1
11199         for line in $filefrag_op
11200         do
11201                 frag_lun=$(echo $line | cut -d: -f5 |
11202                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11203                 ext_len=$(echo $line | cut -d: -f4)
11204                 if (( $frag_lun != $last_lun )); then
11205                         if (( tot_len != 1024 )); then
11206                                 cleanup_130
11207                                 error "FIEMAP on $fm_file failed; returned " \
11208                                 "len $tot_len for OST $last_lun instead of 1024"
11209                                 return
11210                         else
11211                                 (( num_luns += 1 ))
11212                                 tot_len=0
11213                         fi
11214                 fi
11215                 (( tot_len += ext_len ))
11216                 last_lun=$frag_lun
11217         done
11218         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11219                 cleanup_130
11220                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11221                         "luns or wrong len for OST $last_lun"
11222                 return
11223         fi
11224
11225         cleanup_130
11226
11227         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11228 }
11229 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11230
11231 test_130c() {
11232         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11233
11234         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11235         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11236
11237         trap cleanup_130 EXIT RETURN
11238
11239         local fm_file=$DIR/$tfile
11240         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11241         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11242                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11243
11244         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11245                         error "dd failed on $fm_file"
11246
11247         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11248         filefrag_op=$(filefrag -ve -k $fm_file |
11249                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11250
11251         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11252                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11253
11254         IFS=$'\n'
11255         tot_len=0
11256         num_luns=1
11257         for line in $filefrag_op
11258         do
11259                 frag_lun=$(echo $line | cut -d: -f5 |
11260                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11261                 ext_len=$(echo $line | cut -d: -f4)
11262                 if (( $frag_lun != $last_lun )); then
11263                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11264                         if (( logical != 512 )); then
11265                                 cleanup_130
11266                                 error "FIEMAP on $fm_file failed; returned " \
11267                                 "logical start for lun $logical instead of 512"
11268                                 return
11269                         fi
11270                         if (( tot_len != 512 )); then
11271                                 cleanup_130
11272                                 error "FIEMAP on $fm_file failed; returned " \
11273                                 "len $tot_len for OST $last_lun instead of 1024"
11274                                 return
11275                         else
11276                                 (( num_luns += 1 ))
11277                                 tot_len=0
11278                         fi
11279                 fi
11280                 (( tot_len += ext_len ))
11281                 last_lun=$frag_lun
11282         done
11283         if (( num_luns != 2 || tot_len != 512 )); then
11284                 cleanup_130
11285                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11286                         "luns or wrong len for OST $last_lun"
11287                 return
11288         fi
11289
11290         cleanup_130
11291
11292         echo "FIEMAP on 2-stripe file with hole succeeded"
11293 }
11294 run_test 130c "FIEMAP (2-stripe file with hole)"
11295
11296 test_130d() {
11297         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11298
11299         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11300         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11301
11302         trap cleanup_130 EXIT RETURN
11303
11304         local fm_file=$DIR/$tfile
11305         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11306                         error "setstripe on $fm_file"
11307         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11308                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11309
11310         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11311         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11312                 error "dd failed on $fm_file"
11313
11314         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11315         filefrag_op=$(filefrag -ve -k $fm_file |
11316                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11317
11318         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11319                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11320
11321         IFS=$'\n'
11322         tot_len=0
11323         num_luns=1
11324         for line in $filefrag_op
11325         do
11326                 frag_lun=$(echo $line | cut -d: -f5 |
11327                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11328                 ext_len=$(echo $line | cut -d: -f4)
11329                 if (( $frag_lun != $last_lun )); then
11330                         if (( tot_len != 1024 )); then
11331                                 cleanup_130
11332                                 error "FIEMAP on $fm_file failed; returned " \
11333                                 "len $tot_len for OST $last_lun instead of 1024"
11334                                 return
11335                         else
11336                                 (( num_luns += 1 ))
11337                                 tot_len=0
11338                         fi
11339                 fi
11340                 (( tot_len += ext_len ))
11341                 last_lun=$frag_lun
11342         done
11343         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11344                 cleanup_130
11345                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11346                         "luns or wrong len for OST $last_lun"
11347                 return
11348         fi
11349
11350         cleanup_130
11351
11352         echo "FIEMAP on N-stripe file succeeded"
11353 }
11354 run_test 130d "FIEMAP (N-stripe file)"
11355
11356 test_130e() {
11357         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11358
11359         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11360         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11361
11362         trap cleanup_130 EXIT RETURN
11363
11364         local fm_file=$DIR/$tfile
11365         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11366         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11367                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11368
11369         NUM_BLKS=512
11370         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11371         for ((i = 0; i < $NUM_BLKS; i++))
11372         do
11373                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11374         done
11375
11376         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11377         filefrag_op=$(filefrag -ve -k $fm_file |
11378                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11379
11380         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11381                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11382
11383         IFS=$'\n'
11384         tot_len=0
11385         num_luns=1
11386         for line in $filefrag_op
11387         do
11388                 frag_lun=$(echo $line | cut -d: -f5 |
11389                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11390                 ext_len=$(echo $line | cut -d: -f4)
11391                 if (( $frag_lun != $last_lun )); then
11392                         if (( tot_len != $EXPECTED_LEN )); then
11393                                 cleanup_130
11394                                 error "FIEMAP on $fm_file failed; returned " \
11395                                 "len $tot_len for OST $last_lun instead " \
11396                                 "of $EXPECTED_LEN"
11397                                 return
11398                         else
11399                                 (( num_luns += 1 ))
11400                                 tot_len=0
11401                         fi
11402                 fi
11403                 (( tot_len += ext_len ))
11404                 last_lun=$frag_lun
11405         done
11406         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11407                 cleanup_130
11408                 error "FIEMAP on $fm_file failed; returned wrong number " \
11409                         "of luns or wrong len for OST $last_lun"
11410                 return
11411         fi
11412
11413         cleanup_130
11414
11415         echo "FIEMAP with continuation calls succeeded"
11416 }
11417 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11418
11419 test_130f() {
11420         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11421         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11422
11423         local fm_file=$DIR/$tfile
11424         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
11425                 error "multiop create with lov_delay_create on $fm_file"
11426
11427         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11428         filefrag_extents=$(filefrag -vek $fm_file |
11429                            awk '/extents? found/ { print $2 }')
11430         if [[ "$filefrag_extents" != "0" ]]; then
11431                 error "FIEMAP on $fm_file failed; " \
11432                       "returned $filefrag_extents expected 0"
11433         fi
11434
11435         rm -f $fm_file
11436 }
11437 run_test 130f "FIEMAP (unstriped file)"
11438
11439 # Test for writev/readv
11440 test_131a() {
11441         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
11442                 error "writev test failed"
11443         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
11444                 error "readv failed"
11445         rm -f $DIR/$tfile
11446 }
11447 run_test 131a "test iov's crossing stripe boundary for writev/readv"
11448
11449 test_131b() {
11450         local fsize=$((524288 + 1048576 + 1572864))
11451         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
11452                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11453                         error "append writev test failed"
11454
11455         ((fsize += 1572864 + 1048576))
11456         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
11457                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11458                         error "append writev test failed"
11459         rm -f $DIR/$tfile
11460 }
11461 run_test 131b "test append writev"
11462
11463 test_131c() {
11464         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
11465         error "NOT PASS"
11466 }
11467 run_test 131c "test read/write on file w/o objects"
11468
11469 test_131d() {
11470         rwv -f $DIR/$tfile -w -n 1 1572864
11471         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
11472         if [ "$NOB" != 1572864 ]; then
11473                 error "Short read filed: read $NOB bytes instead of 1572864"
11474         fi
11475         rm -f $DIR/$tfile
11476 }
11477 run_test 131d "test short read"
11478
11479 test_131e() {
11480         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
11481         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
11482         error "read hitting hole failed"
11483         rm -f $DIR/$tfile
11484 }
11485 run_test 131e "test read hitting hole"
11486
11487 check_stats() {
11488         local facet=$1
11489         local op=$2
11490         local want=${3:-0}
11491         local res
11492
11493         case $facet in
11494         mds*) res=$(do_facet $facet \
11495                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
11496                  ;;
11497         ost*) res=$(do_facet $facet \
11498                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
11499                  ;;
11500         *) error "Wrong facet '$facet'" ;;
11501         esac
11502         [ "$res" ] || error "The counter for $op on $facet was not incremented"
11503         # if the argument $3 is zero, it means any stat increment is ok.
11504         if [[ $want -gt 0 ]]; then
11505                 local count=$(echo $res | awk '{ print $2 }')
11506                 [[ $count -ne $want ]] &&
11507                         error "The $op counter on $facet is $count, not $want"
11508         fi
11509 }
11510
11511 test_133a() {
11512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11513         remote_ost_nodsh && skip "remote OST with nodsh"
11514         remote_mds_nodsh && skip "remote MDS with nodsh"
11515         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11516                 skip_env "MDS doesn't support rename stats"
11517
11518         local testdir=$DIR/${tdir}/stats_testdir
11519
11520         mkdir -p $DIR/${tdir}
11521
11522         # clear stats.
11523         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11524         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11525
11526         # verify mdt stats first.
11527         mkdir ${testdir} || error "mkdir failed"
11528         check_stats $SINGLEMDS "mkdir" 1
11529         touch ${testdir}/${tfile} || error "touch failed"
11530         check_stats $SINGLEMDS "open" 1
11531         check_stats $SINGLEMDS "close" 1
11532         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11533                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11534                 check_stats $SINGLEMDS "mknod" 2
11535         }
11536         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11537         check_stats $SINGLEMDS "unlink" 1
11538         rm -f ${testdir}/${tfile} || error "file remove failed"
11539         check_stats $SINGLEMDS "unlink" 2
11540
11541         # remove working dir and check mdt stats again.
11542         rmdir ${testdir} || error "rmdir failed"
11543         check_stats $SINGLEMDS "rmdir" 1
11544
11545         local testdir1=$DIR/${tdir}/stats_testdir1
11546         mkdir -p ${testdir}
11547         mkdir -p ${testdir1}
11548         touch ${testdir1}/test1
11549         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11550         check_stats $SINGLEMDS "crossdir_rename" 1
11551
11552         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11553         check_stats $SINGLEMDS "samedir_rename" 1
11554
11555         rm -rf $DIR/${tdir}
11556 }
11557 run_test 133a "Verifying MDT stats ========================================"
11558
11559 test_133b() {
11560         local res
11561
11562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11563         remote_ost_nodsh && skip "remote OST with nodsh"
11564         remote_mds_nodsh && skip "remote MDS with nodsh"
11565
11566         local testdir=$DIR/${tdir}/stats_testdir
11567
11568         mkdir -p ${testdir} || error "mkdir failed"
11569         touch ${testdir}/${tfile} || error "touch failed"
11570         cancel_lru_locks mdc
11571
11572         # clear stats.
11573         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11574         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11575
11576         # extra mdt stats verification.
11577         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11578         check_stats $SINGLEMDS "setattr" 1
11579         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11580         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11581         then            # LU-1740
11582                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11583                 check_stats $SINGLEMDS "getattr" 1
11584         fi
11585         rm -rf $DIR/${tdir}
11586
11587         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11588         # so the check below is not reliable
11589         [ $MDSCOUNT -eq 1 ] || return 0
11590
11591         # Sleep to avoid a cached response.
11592         #define OBD_STATFS_CACHE_SECONDS 1
11593         sleep 2
11594         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11595         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11596         $LFS df || error "lfs failed"
11597         check_stats $SINGLEMDS "statfs" 1
11598
11599         # check aggregated statfs (LU-10018)
11600         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11601                 return 0
11602         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11603                 return 0
11604         sleep 2
11605         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11606         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11607         df $DIR
11608         check_stats $SINGLEMDS "statfs" 1
11609
11610         # We want to check that the client didn't send OST_STATFS to
11611         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11612         # extra care is needed here.
11613         if remote_mds; then
11614                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11615                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11616
11617                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11618                 [ "$res" ] && error "OST got STATFS"
11619         fi
11620
11621         return 0
11622 }
11623 run_test 133b "Verifying extra MDT stats =================================="
11624
11625 test_133c() {
11626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11627         remote_ost_nodsh && skip "remote OST with nodsh"
11628         remote_mds_nodsh && skip "remote MDS with nodsh"
11629
11630         local testdir=$DIR/$tdir/stats_testdir
11631
11632         test_mkdir -p $testdir
11633
11634         # verify obdfilter stats.
11635         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11636         sync
11637         cancel_lru_locks osc
11638         wait_delete_completed
11639
11640         # clear stats.
11641         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11642         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11643
11644         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11645                 error "dd failed"
11646         sync
11647         cancel_lru_locks osc
11648         check_stats ost1 "write" 1
11649
11650         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11651         check_stats ost1 "read" 1
11652
11653         > $testdir/$tfile || error "truncate failed"
11654         check_stats ost1 "punch" 1
11655
11656         rm -f $testdir/$tfile || error "file remove failed"
11657         wait_delete_completed
11658         check_stats ost1 "destroy" 1
11659
11660         rm -rf $DIR/$tdir
11661 }
11662 run_test 133c "Verifying OST stats ========================================"
11663
11664 order_2() {
11665         local value=$1
11666         local orig=$value
11667         local order=1
11668
11669         while [ $value -ge 2 ]; do
11670                 order=$((order*2))
11671                 value=$((value/2))
11672         done
11673
11674         if [ $orig -gt $order ]; then
11675                 order=$((order*2))
11676         fi
11677         echo $order
11678 }
11679
11680 size_in_KMGT() {
11681     local value=$1
11682     local size=('K' 'M' 'G' 'T');
11683     local i=0
11684     local size_string=$value
11685
11686     while [ $value -ge 1024 ]; do
11687         if [ $i -gt 3 ]; then
11688             #T is the biggest unit we get here, if that is bigger,
11689             #just return XXXT
11690             size_string=${value}T
11691             break
11692         fi
11693         value=$((value >> 10))
11694         if [ $value -lt 1024 ]; then
11695             size_string=${value}${size[$i]}
11696             break
11697         fi
11698         i=$((i + 1))
11699     done
11700
11701     echo $size_string
11702 }
11703
11704 get_rename_size() {
11705         local size=$1
11706         local context=${2:-.}
11707         local sample=$(do_facet $SINGLEMDS $LCTL \
11708                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11709                 grep -A1 $context |
11710                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11711         echo $sample
11712 }
11713
11714 test_133d() {
11715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11716         remote_ost_nodsh && skip "remote OST with nodsh"
11717         remote_mds_nodsh && skip "remote MDS with nodsh"
11718         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11719                 skip_env "MDS doesn't support rename stats"
11720
11721         local testdir1=$DIR/${tdir}/stats_testdir1
11722         local testdir2=$DIR/${tdir}/stats_testdir2
11723         mkdir -p $DIR/${tdir}
11724
11725         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11726
11727         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11728         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11729
11730         createmany -o $testdir1/test 512 || error "createmany failed"
11731
11732         # check samedir rename size
11733         mv ${testdir1}/test0 ${testdir1}/test_0
11734
11735         local testdir1_size=$(ls -l $DIR/${tdir} |
11736                 awk '/stats_testdir1/ {print $5}')
11737         local testdir2_size=$(ls -l $DIR/${tdir} |
11738                 awk '/stats_testdir2/ {print $5}')
11739
11740         testdir1_size=$(order_2 $testdir1_size)
11741         testdir2_size=$(order_2 $testdir2_size)
11742
11743         testdir1_size=$(size_in_KMGT $testdir1_size)
11744         testdir2_size=$(size_in_KMGT $testdir2_size)
11745
11746         echo "source rename dir size: ${testdir1_size}"
11747         echo "target rename dir size: ${testdir2_size}"
11748
11749         local cmd="do_facet $SINGLEMDS $LCTL "
11750         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11751
11752         eval $cmd || error "$cmd failed"
11753         local samedir=$($cmd | grep 'same_dir')
11754         local same_sample=$(get_rename_size $testdir1_size)
11755         [ -z "$samedir" ] && error "samedir_rename_size count error"
11756         [[ $same_sample -eq 1 ]] ||
11757                 error "samedir_rename_size error $same_sample"
11758         echo "Check same dir rename stats success"
11759
11760         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11761
11762         # check crossdir rename size
11763         mv ${testdir1}/test_0 ${testdir2}/test_0
11764
11765         testdir1_size=$(ls -l $DIR/${tdir} |
11766                 awk '/stats_testdir1/ {print $5}')
11767         testdir2_size=$(ls -l $DIR/${tdir} |
11768                 awk '/stats_testdir2/ {print $5}')
11769
11770         testdir1_size=$(order_2 $testdir1_size)
11771         testdir2_size=$(order_2 $testdir2_size)
11772
11773         testdir1_size=$(size_in_KMGT $testdir1_size)
11774         testdir2_size=$(size_in_KMGT $testdir2_size)
11775
11776         echo "source rename dir size: ${testdir1_size}"
11777         echo "target rename dir size: ${testdir2_size}"
11778
11779         eval $cmd || error "$cmd failed"
11780         local crossdir=$($cmd | grep 'crossdir')
11781         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11782         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11783         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11784         [[ $src_sample -eq 1 ]] ||
11785                 error "crossdir_rename_size error $src_sample"
11786         [[ $tgt_sample -eq 1 ]] ||
11787                 error "crossdir_rename_size error $tgt_sample"
11788         echo "Check cross dir rename stats success"
11789         rm -rf $DIR/${tdir}
11790 }
11791 run_test 133d "Verifying rename_stats ========================================"
11792
11793 test_133e() {
11794         remote_mds_nodsh && skip "remote MDS with nodsh"
11795         remote_ost_nodsh && skip "remote OST with nodsh"
11796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11797
11798         local testdir=$DIR/${tdir}/stats_testdir
11799         local ctr f0 f1 bs=32768 count=42 sum
11800
11801         mkdir -p ${testdir} || error "mkdir failed"
11802
11803         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11804
11805         for ctr in {write,read}_bytes; do
11806                 sync
11807                 cancel_lru_locks osc
11808
11809                 do_facet ost1 $LCTL set_param -n \
11810                         "obdfilter.*.exports.clear=clear"
11811
11812                 if [ $ctr = write_bytes ]; then
11813                         f0=/dev/zero
11814                         f1=${testdir}/${tfile}
11815                 else
11816                         f0=${testdir}/${tfile}
11817                         f1=/dev/null
11818                 fi
11819
11820                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11821                         error "dd failed"
11822                 sync
11823                 cancel_lru_locks osc
11824
11825                 sum=$(do_facet ost1 $LCTL get_param \
11826                         "obdfilter.*.exports.*.stats" |
11827                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11828                                 $1 == ctr { sum += $7 }
11829                                 END { printf("%0.0f", sum) }')
11830
11831                 if ((sum != bs * count)); then
11832                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11833                 fi
11834         done
11835
11836         rm -rf $DIR/${tdir}
11837 }
11838 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11839
11840 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11841
11842 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11843 # not honor the -ignore_readdir_race option correctly. So we call
11844 # error_ignore() rather than error() in these cases. See LU-11152.
11845 error_133() {
11846         if (find --version; do_facet mds1 find --version) |
11847                 grep -q '\b4\.5\.1[1-4]\b'; then
11848                 error_ignore LU-11152 "$@"
11849         else
11850                 error "$@"
11851         fi
11852 }
11853
11854 test_133f() {
11855         # First without trusting modes.
11856         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11857         echo "proc_dirs='$proc_dirs'"
11858         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11859         find $proc_dirs -exec cat '{}' \; &> /dev/null
11860
11861         # Second verifying readability.
11862         $LCTL get_param -R '*' &> /dev/null
11863
11864         # Verifing writability with badarea_io.
11865         find $proc_dirs \
11866                 -ignore_readdir_race \
11867                 -type f \
11868                 -not -name force_lbug \
11869                 -not -name changelog_mask \
11870                 -exec badarea_io '{}' \; ||
11871                         error_133 "find $proc_dirs failed"
11872 }
11873 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11874
11875 test_133g() {
11876         remote_mds_nodsh && skip "remote MDS with nodsh"
11877         remote_ost_nodsh && skip "remote OST with nodsh"
11878
11879         # eventually, this can also be replaced with "lctl get_param -R",
11880         # but not until that option is always available on the server
11881         local facet
11882         for facet in mds1 ost1; do
11883                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11884                         skip_noexit "Too old lustre on $facet"
11885                 local facet_proc_dirs=$(do_facet $facet \
11886                                         \\\ls -d $proc_regexp 2>/dev/null)
11887                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11888                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11889                 do_facet $facet find $facet_proc_dirs \
11890                         ! -name req_history \
11891                         -exec cat '{}' \\\; &> /dev/null
11892
11893                 do_facet $facet find $facet_proc_dirs \
11894                         ! -name req_history \
11895                         -type f \
11896                         -exec cat '{}' \\\; &> /dev/null ||
11897                                 error "proc file read failed"
11898
11899                 do_facet $facet find $facet_proc_dirs \
11900                         -ignore_readdir_race \
11901                         -type f \
11902                         -not -name force_lbug \
11903                         -not -name changelog_mask \
11904                         -exec badarea_io '{}' \\\; ||
11905                                 error_133 "$facet find $facet_proc_dirs failed"
11906         done
11907
11908         # remount the FS in case writes/reads /proc break the FS
11909         cleanup || error "failed to unmount"
11910         setup || error "failed to setup"
11911         true
11912 }
11913 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11914
11915 test_133h() {
11916         remote_mds_nodsh && skip "remote MDS with nodsh"
11917         remote_ost_nodsh && skip "remote OST with nodsh"
11918         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11919                 skip "Need MDS version at least 2.9.54"
11920
11921         local facet
11922
11923         for facet in client mds1 ost1; do
11924                 local facet_proc_dirs=$(do_facet $facet \
11925                                         \\\ls -d $proc_regexp 2> /dev/null)
11926                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11927                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11928                 # Get the list of files that are missing the terminating newline
11929                 local missing=($(do_facet $facet \
11930                         find ${facet_proc_dirs} -type f \|              \
11931                                 while read F\; do                       \
11932                                         awk -v FS='\v' -v RS='\v\v'     \
11933                                         "'END { if(NR>0 &&              \
11934                                         \\\$NF !~ /.*\\\n\$/)           \
11935                                                 print FILENAME}'"       \
11936                                         '\$F'\;                         \
11937                                 done 2>/dev/null))
11938                 [ ${#missing[*]} -eq 0 ] ||
11939                         error "files do not end with newline: ${missing[*]}"
11940         done
11941 }
11942 run_test 133h "Proc files should end with newlines"
11943
11944 test_134a() {
11945         remote_mds_nodsh && skip "remote MDS with nodsh"
11946         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11947                 skip "Need MDS version at least 2.7.54"
11948
11949         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11950         cancel_lru_locks mdc
11951
11952         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11953         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11954         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11955
11956         local nr=1000
11957         createmany -o $DIR/$tdir/f $nr ||
11958                 error "failed to create $nr files in $DIR/$tdir"
11959         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11960
11961         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11962         do_facet mds1 $LCTL set_param fail_loc=0x327
11963         do_facet mds1 $LCTL set_param fail_val=500
11964         touch $DIR/$tdir/m
11965
11966         echo "sleep 10 seconds ..."
11967         sleep 10
11968         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11969
11970         do_facet mds1 $LCTL set_param fail_loc=0
11971         do_facet mds1 $LCTL set_param fail_val=0
11972         [ $lck_cnt -lt $unused ] ||
11973                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11974
11975         rm $DIR/$tdir/m
11976         unlinkmany $DIR/$tdir/f $nr
11977 }
11978 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11979
11980 test_134b() {
11981         remote_mds_nodsh && skip "remote MDS with nodsh"
11982         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11983                 skip "Need MDS version at least 2.7.54"
11984
11985         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11986         cancel_lru_locks mdc
11987
11988         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11989                         ldlm.lock_reclaim_threshold_mb)
11990         # disable reclaim temporarily
11991         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11992
11993         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11994         do_facet mds1 $LCTL set_param fail_loc=0x328
11995         do_facet mds1 $LCTL set_param fail_val=500
11996
11997         $LCTL set_param debug=+trace
11998
11999         local nr=600
12000         createmany -o $DIR/$tdir/f $nr &
12001         local create_pid=$!
12002
12003         echo "Sleep $TIMEOUT seconds ..."
12004         sleep $TIMEOUT
12005         if ! ps -p $create_pid  > /dev/null 2>&1; then
12006                 do_facet mds1 $LCTL set_param fail_loc=0
12007                 do_facet mds1 $LCTL set_param fail_val=0
12008                 do_facet mds1 $LCTL set_param \
12009                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12010                 error "createmany finished incorrectly!"
12011         fi
12012         do_facet mds1 $LCTL set_param fail_loc=0
12013         do_facet mds1 $LCTL set_param fail_val=0
12014         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12015         wait $create_pid || return 1
12016
12017         unlinkmany $DIR/$tdir/f $nr
12018 }
12019 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12020
12021 test_140() { #bug-17379
12022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12023
12024         test_mkdir $DIR/$tdir
12025         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12026         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12027
12028         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12029         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12030         local i=0
12031         while i=$((i + 1)); do
12032                 test_mkdir $i
12033                 cd $i || error "Changing to $i"
12034                 ln -s ../stat stat || error "Creating stat symlink"
12035                 # Read the symlink until ELOOP present,
12036                 # not LBUGing the system is considered success,
12037                 # we didn't overrun the stack.
12038                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12039                 if [ $ret -ne 0 ]; then
12040                         if [ $ret -eq 40 ]; then
12041                                 break  # -ELOOP
12042                         else
12043                                 error "Open stat symlink"
12044                                         return
12045                         fi
12046                 fi
12047         done
12048         i=$((i - 1))
12049         echo "The symlink depth = $i"
12050         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12051                 error "Invalid symlink depth"
12052
12053         # Test recursive symlink
12054         ln -s symlink_self symlink_self
12055         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12056         echo "open symlink_self returns $ret"
12057         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12058 }
12059 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12060
12061 test_150() {
12062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12063
12064         local TF="$TMP/$tfile"
12065
12066         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12067         cp $TF $DIR/$tfile
12068         cancel_lru_locks $OSC
12069         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12070         remount_client $MOUNT
12071         df -P $MOUNT
12072         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12073
12074         $TRUNCATE $TF 6000
12075         $TRUNCATE $DIR/$tfile 6000
12076         cancel_lru_locks $OSC
12077         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12078
12079         echo "12345" >>$TF
12080         echo "12345" >>$DIR/$tfile
12081         cancel_lru_locks $OSC
12082         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12083
12084         echo "12345" >>$TF
12085         echo "12345" >>$DIR/$tfile
12086         cancel_lru_locks $OSC
12087         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12088
12089         rm -f $TF
12090         true
12091 }
12092 run_test 150 "truncate/append tests"
12093
12094 #LU-2902 roc_hit was not able to read all values from lproc
12095 function roc_hit_init() {
12096         local list=$(comma_list $(osts_nodes))
12097         local dir=$DIR/$tdir-check
12098         local file=$dir/$tfile
12099         local BEFORE
12100         local AFTER
12101         local idx
12102
12103         test_mkdir $dir
12104         #use setstripe to do a write to every ost
12105         for i in $(seq 0 $((OSTCOUNT-1))); do
12106                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12107                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12108                 idx=$(printf %04x $i)
12109                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12110                         awk '$1 == "cache_access" {sum += $7}
12111                                 END { printf("%0.0f", sum) }')
12112
12113                 cancel_lru_locks osc
12114                 cat $file >/dev/null
12115
12116                 AFTER=$(get_osd_param $list *OST*$idx stats |
12117                         awk '$1 == "cache_access" {sum += $7}
12118                                 END { printf("%0.0f", sum) }')
12119
12120                 echo BEFORE:$BEFORE AFTER:$AFTER
12121                 if ! let "AFTER - BEFORE == 4"; then
12122                         rm -rf $dir
12123                         error "roc_hit is not safe to use"
12124                 fi
12125                 rm $file
12126         done
12127
12128         rm -rf $dir
12129 }
12130
12131 function roc_hit() {
12132         local list=$(comma_list $(osts_nodes))
12133         echo $(get_osd_param $list '' stats |
12134                 awk '$1 == "cache_hit" {sum += $7}
12135                         END { printf("%0.0f", sum) }')
12136 }
12137
12138 function set_cache() {
12139         local on=1
12140
12141         if [ "$2" == "off" ]; then
12142                 on=0;
12143         fi
12144         local list=$(comma_list $(osts_nodes))
12145         set_osd_param $list '' $1_cache_enable $on
12146
12147         cancel_lru_locks osc
12148 }
12149
12150 test_151() {
12151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12152         remote_ost_nodsh && skip "remote OST with nodsh"
12153
12154         local CPAGES=3
12155         local list=$(comma_list $(osts_nodes))
12156
12157         # check whether obdfilter is cache capable at all
12158         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12159                 skip "not cache-capable obdfilter"
12160         fi
12161
12162         # check cache is enabled on all obdfilters
12163         if get_osd_param $list '' read_cache_enable | grep 0; then
12164                 skip "oss cache is disabled"
12165         fi
12166
12167         set_osd_param $list '' writethrough_cache_enable 1
12168
12169         # check write cache is enabled on all obdfilters
12170         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12171                 skip "oss write cache is NOT enabled"
12172         fi
12173
12174         roc_hit_init
12175
12176         #define OBD_FAIL_OBD_NO_LRU  0x609
12177         do_nodes $list $LCTL set_param fail_loc=0x609
12178
12179         # pages should be in the case right after write
12180         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12181                 error "dd failed"
12182
12183         local BEFORE=$(roc_hit)
12184         cancel_lru_locks osc
12185         cat $DIR/$tfile >/dev/null
12186         local AFTER=$(roc_hit)
12187
12188         do_nodes $list $LCTL set_param fail_loc=0
12189
12190         if ! let "AFTER - BEFORE == CPAGES"; then
12191                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12192         fi
12193
12194         # the following read invalidates the cache
12195         cancel_lru_locks osc
12196         set_osd_param $list '' read_cache_enable 0
12197         cat $DIR/$tfile >/dev/null
12198
12199         # now data shouldn't be found in the cache
12200         BEFORE=$(roc_hit)
12201         cancel_lru_locks osc
12202         cat $DIR/$tfile >/dev/null
12203         AFTER=$(roc_hit)
12204         if let "AFTER - BEFORE != 0"; then
12205                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12206         fi
12207
12208         set_osd_param $list '' read_cache_enable 1
12209         rm -f $DIR/$tfile
12210 }
12211 run_test 151 "test cache on oss and controls ==============================="
12212
12213 test_152() {
12214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12215
12216         local TF="$TMP/$tfile"
12217
12218         # simulate ENOMEM during write
12219 #define OBD_FAIL_OST_NOMEM      0x226
12220         lctl set_param fail_loc=0x80000226
12221         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12222         cp $TF $DIR/$tfile
12223         sync || error "sync failed"
12224         lctl set_param fail_loc=0
12225
12226         # discard client's cache
12227         cancel_lru_locks osc
12228
12229         # simulate ENOMEM during read
12230         lctl set_param fail_loc=0x80000226
12231         cmp $TF $DIR/$tfile || error "cmp failed"
12232         lctl set_param fail_loc=0
12233
12234         rm -f $TF
12235 }
12236 run_test 152 "test read/write with enomem ============================"
12237
12238 test_153() {
12239         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12240 }
12241 run_test 153 "test if fdatasync does not crash ======================="
12242
12243 dot_lustre_fid_permission_check() {
12244         local fid=$1
12245         local ffid=$MOUNT/.lustre/fid/$fid
12246         local test_dir=$2
12247
12248         echo "stat fid $fid"
12249         stat $ffid > /dev/null || error "stat $ffid failed."
12250         echo "touch fid $fid"
12251         touch $ffid || error "touch $ffid failed."
12252         echo "write to fid $fid"
12253         cat /etc/hosts > $ffid || error "write $ffid failed."
12254         echo "read fid $fid"
12255         diff /etc/hosts $ffid || error "read $ffid failed."
12256         echo "append write to fid $fid"
12257         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12258         echo "rename fid $fid"
12259         mv $ffid $test_dir/$tfile.1 &&
12260                 error "rename $ffid to $tfile.1 should fail."
12261         touch $test_dir/$tfile.1
12262         mv $test_dir/$tfile.1 $ffid &&
12263                 error "rename $tfile.1 to $ffid should fail."
12264         rm -f $test_dir/$tfile.1
12265         echo "truncate fid $fid"
12266         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12267         echo "link fid $fid"
12268         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12269         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12270                 echo "setfacl fid $fid"
12271                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12272                 echo "getfacl fid $fid"
12273                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12274         fi
12275         echo "unlink fid $fid"
12276         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12277         echo "mknod fid $fid"
12278         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12279
12280         fid=[0xf00000400:0x1:0x0]
12281         ffid=$MOUNT/.lustre/fid/$fid
12282
12283         echo "stat non-exist fid $fid"
12284         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12285         echo "write to non-exist fid $fid"
12286         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12287         echo "link new fid $fid"
12288         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12289
12290         mkdir -p $test_dir/$tdir
12291         touch $test_dir/$tdir/$tfile
12292         fid=$($LFS path2fid $test_dir/$tdir)
12293         rc=$?
12294         [ $rc -ne 0 ] &&
12295                 error "error: could not get fid for $test_dir/$dir/$tfile."
12296
12297         ffid=$MOUNT/.lustre/fid/$fid
12298
12299         echo "ls $fid"
12300         ls $ffid > /dev/null || error "ls $ffid failed."
12301         echo "touch $fid/$tfile.1"
12302         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12303
12304         echo "touch $MOUNT/.lustre/fid/$tfile"
12305         touch $MOUNT/.lustre/fid/$tfile && \
12306                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12307
12308         echo "setxattr to $MOUNT/.lustre/fid"
12309         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12310
12311         echo "listxattr for $MOUNT/.lustre/fid"
12312         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12313
12314         echo "delxattr from $MOUNT/.lustre/fid"
12315         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12316
12317         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12318         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12319                 error "touch invalid fid should fail."
12320
12321         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12322         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12323                 error "touch non-normal fid should fail."
12324
12325         echo "rename $tdir to $MOUNT/.lustre/fid"
12326         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12327                 error "rename to $MOUNT/.lustre/fid should fail."
12328
12329         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12330         then            # LU-3547
12331                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12332                 local new_obf_mode=777
12333
12334                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12335                 chmod $new_obf_mode $DIR/.lustre/fid ||
12336                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12337
12338                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12339                 [ $obf_mode -eq $new_obf_mode ] ||
12340                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12341
12342                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12343                 chmod $old_obf_mode $DIR/.lustre/fid ||
12344                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12345         fi
12346
12347         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12348         fid=$($LFS path2fid $test_dir/$tfile-2)
12349
12350         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12351         then # LU-5424
12352                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12353                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12354                         error "create lov data thru .lustre failed"
12355         fi
12356         echo "cp /etc/passwd $test_dir/$tfile-2"
12357         cp /etc/passwd $test_dir/$tfile-2 ||
12358                 error "copy to $test_dir/$tfile-2 failed."
12359         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12360         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12361                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12362
12363         rm -rf $test_dir/tfile.lnk
12364         rm -rf $test_dir/$tfile-2
12365 }
12366
12367 test_154A() {
12368         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12369                 skip "Need MDS version at least 2.4.1"
12370
12371         local tf=$DIR/$tfile
12372         touch $tf
12373
12374         local fid=$($LFS path2fid $tf)
12375         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12376
12377         # check that we get the same pathname back
12378         local found=$($LFS fid2path $MOUNT "$fid")
12379         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12380         [ "$found" == "$tf" ] ||
12381                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12382 }
12383 run_test 154A "lfs path2fid and fid2path basic checks"
12384
12385 test_154B() {
12386         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12387                 skip "Need MDS version at least 2.4.1"
12388
12389         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12390         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12391         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12392         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12393
12394         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12395         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12396
12397         # check that we get the same pathname
12398         echo "PFID: $PFID, name: $name"
12399         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12400         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12401         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12402                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12403
12404         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12405 }
12406 run_test 154B "verify the ll_decode_linkea tool"
12407
12408 test_154a() {
12409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12410         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12411         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12412                 skip "Need MDS version at least 2.2.51"
12413         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12414
12415         cp /etc/hosts $DIR/$tfile
12416
12417         fid=$($LFS path2fid $DIR/$tfile)
12418         rc=$?
12419         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
12420
12421         dot_lustre_fid_permission_check "$fid" $DIR ||
12422                 error "dot lustre permission check $fid failed"
12423
12424         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
12425
12426         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
12427
12428         touch $MOUNT/.lustre/file &&
12429                 error "creation is not allowed under .lustre"
12430
12431         mkdir $MOUNT/.lustre/dir &&
12432                 error "mkdir is not allowed under .lustre"
12433
12434         rm -rf $DIR/$tfile
12435 }
12436 run_test 154a "Open-by-FID"
12437
12438 test_154b() {
12439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12440         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12441         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12442         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12443                 skip "Need MDS version at least 2.2.51"
12444
12445         local remote_dir=$DIR/$tdir/remote_dir
12446         local MDTIDX=1
12447         local rc=0
12448
12449         mkdir -p $DIR/$tdir
12450         $LFS mkdir -i $MDTIDX $remote_dir ||
12451                 error "create remote directory failed"
12452
12453         cp /etc/hosts $remote_dir/$tfile
12454
12455         fid=$($LFS path2fid $remote_dir/$tfile)
12456         rc=$?
12457         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
12458
12459         dot_lustre_fid_permission_check "$fid" $remote_dir ||
12460                 error "dot lustre permission check $fid failed"
12461         rm -rf $DIR/$tdir
12462 }
12463 run_test 154b "Open-by-FID for remote directory"
12464
12465 test_154c() {
12466         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12467                 skip "Need MDS version at least 2.4.1"
12468
12469         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
12470         local FID1=$($LFS path2fid $DIR/$tfile.1)
12471         local FID2=$($LFS path2fid $DIR/$tfile.2)
12472         local FID3=$($LFS path2fid $DIR/$tfile.3)
12473
12474         local N=1
12475         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
12476                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
12477                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
12478                 local want=FID$N
12479                 [ "$FID" = "${!want}" ] ||
12480                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
12481                 N=$((N + 1))
12482         done
12483
12484         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
12485         do
12486                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
12487                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
12488                 N=$((N + 1))
12489         done
12490 }
12491 run_test 154c "lfs path2fid and fid2path multiple arguments"
12492
12493 test_154d() {
12494         remote_mds_nodsh && skip "remote MDS with nodsh"
12495         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
12496                 skip "Need MDS version at least 2.5.53"
12497
12498         if remote_mds; then
12499                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
12500         else
12501                 nid="0@lo"
12502         fi
12503         local proc_ofile="mdt.*.exports.'$nid'.open_files"
12504         local fd
12505         local cmd
12506
12507         rm -f $DIR/$tfile
12508         touch $DIR/$tfile
12509
12510         local fid=$($LFS path2fid $DIR/$tfile)
12511         # Open the file
12512         fd=$(free_fd)
12513         cmd="exec $fd<$DIR/$tfile"
12514         eval $cmd
12515         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
12516         echo "$fid_list" | grep "$fid"
12517         rc=$?
12518
12519         cmd="exec $fd>/dev/null"
12520         eval $cmd
12521         if [ $rc -ne 0 ]; then
12522                 error "FID $fid not found in open files list $fid_list"
12523         fi
12524 }
12525 run_test 154d "Verify open file fid"
12526
12527 test_154e()
12528 {
12529         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12530                 skip "Need MDS version at least 2.6.50"
12531
12532         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12533                 error ".lustre returned by readdir"
12534         fi
12535 }
12536 run_test 154e ".lustre is not returned by readdir"
12537
12538 test_154f() {
12539         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12540
12541         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12542         test_mkdir -p -c1 $DIR/$tdir/d
12543         # test dirs inherit from its stripe
12544         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12545         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12546         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12547         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12548         touch $DIR/f
12549
12550         # get fid of parents
12551         local FID0=$($LFS path2fid $DIR/$tdir/d)
12552         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12553         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12554         local FID3=$($LFS path2fid $DIR)
12555
12556         # check that path2fid --parents returns expected <parent_fid>/name
12557         # 1) test for a directory (single parent)
12558         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12559         [ "$parent" == "$FID0/foo1" ] ||
12560                 error "expected parent: $FID0/foo1, got: $parent"
12561
12562         # 2) test for a file with nlink > 1 (multiple parents)
12563         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12564         echo "$parent" | grep -F "$FID1/$tfile" ||
12565                 error "$FID1/$tfile not returned in parent list"
12566         echo "$parent" | grep -F "$FID2/link" ||
12567                 error "$FID2/link not returned in parent list"
12568
12569         # 3) get parent by fid
12570         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12571         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12572         echo "$parent" | grep -F "$FID1/$tfile" ||
12573                 error "$FID1/$tfile not returned in parent list (by fid)"
12574         echo "$parent" | grep -F "$FID2/link" ||
12575                 error "$FID2/link not returned in parent list (by fid)"
12576
12577         # 4) test for entry in root directory
12578         parent=$($LFS path2fid --parents $DIR/f)
12579         echo "$parent" | grep -F "$FID3/f" ||
12580                 error "$FID3/f not returned in parent list"
12581
12582         # 5) test it on root directory
12583         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12584                 error "$MOUNT should not have parents"
12585
12586         # enable xattr caching and check that linkea is correctly updated
12587         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12588         save_lustre_params client "llite.*.xattr_cache" > $save
12589         lctl set_param llite.*.xattr_cache 1
12590
12591         # 6.1) linkea update on rename
12592         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12593
12594         # get parents by fid
12595         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12596         # foo1 should no longer be returned in parent list
12597         echo "$parent" | grep -F "$FID1" &&
12598                 error "$FID1 should no longer be in parent list"
12599         # the new path should appear
12600         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12601                 error "$FID2/$tfile.moved is not in parent list"
12602
12603         # 6.2) linkea update on unlink
12604         rm -f $DIR/$tdir/d/foo2/link
12605         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12606         # foo2/link should no longer be returned in parent list
12607         echo "$parent" | grep -F "$FID2/link" &&
12608                 error "$FID2/link should no longer be in parent list"
12609         true
12610
12611         rm -f $DIR/f
12612         restore_lustre_params < $save
12613         rm -f $save
12614 }
12615 run_test 154f "get parent fids by reading link ea"
12616
12617 test_154g()
12618 {
12619         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12620         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12621            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12622                 skip "Need MDS version at least 2.6.92"
12623
12624         mkdir -p $DIR/$tdir
12625         llapi_fid_test -d $DIR/$tdir
12626 }
12627 run_test 154g "various llapi FID tests"
12628
12629 test_155_small_load() {
12630     local temp=$TMP/$tfile
12631     local file=$DIR/$tfile
12632
12633     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12634         error "dd of=$temp bs=6096 count=1 failed"
12635     cp $temp $file
12636     cancel_lru_locks $OSC
12637     cmp $temp $file || error "$temp $file differ"
12638
12639     $TRUNCATE $temp 6000
12640     $TRUNCATE $file 6000
12641     cmp $temp $file || error "$temp $file differ (truncate1)"
12642
12643     echo "12345" >>$temp
12644     echo "12345" >>$file
12645     cmp $temp $file || error "$temp $file differ (append1)"
12646
12647     echo "12345" >>$temp
12648     echo "12345" >>$file
12649     cmp $temp $file || error "$temp $file differ (append2)"
12650
12651     rm -f $temp $file
12652     true
12653 }
12654
12655 test_155_big_load() {
12656         remote_ost_nodsh && skip "remote OST with nodsh"
12657
12658         local temp=$TMP/$tfile
12659         local file=$DIR/$tfile
12660
12661         free_min_max
12662         local cache_size=$(do_facet ost$((MAXI+1)) \
12663                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12664         local large_file_size=$((cache_size * 2))
12665
12666         echo "OSS cache size: $cache_size KB"
12667         echo "Large file size: $large_file_size KB"
12668
12669         [ $MAXV -le $large_file_size ] &&
12670                 skip_env "max available OST size needs > $large_file_size KB"
12671
12672         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12673
12674         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12675                 error "dd of=$temp bs=$large_file_size count=1k failed"
12676         cp $temp $file
12677         ls -lh $temp $file
12678         cancel_lru_locks osc
12679         cmp $temp $file || error "$temp $file differ"
12680
12681         rm -f $temp $file
12682         true
12683 }
12684
12685 save_writethrough() {
12686         local facets=$(get_facets OST)
12687
12688         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12689 }
12690
12691 test_155a() {
12692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12693
12694         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12695
12696         save_writethrough $p
12697
12698         set_cache read on
12699         set_cache writethrough on
12700         test_155_small_load
12701         restore_lustre_params < $p
12702         rm -f $p
12703 }
12704 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12705
12706 test_155b() {
12707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12708
12709         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12710
12711         save_writethrough $p
12712
12713         set_cache read on
12714         set_cache writethrough off
12715         test_155_small_load
12716         restore_lustre_params < $p
12717         rm -f $p
12718 }
12719 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12720
12721 test_155c() {
12722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12723
12724         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12725
12726         save_writethrough $p
12727
12728         set_cache read off
12729         set_cache writethrough on
12730         test_155_small_load
12731         restore_lustre_params < $p
12732         rm -f $p
12733 }
12734 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12735
12736 test_155d() {
12737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12738
12739         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12740
12741         save_writethrough $p
12742
12743         set_cache read off
12744         set_cache writethrough off
12745         test_155_small_load
12746         restore_lustre_params < $p
12747         rm -f $p
12748 }
12749 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12750
12751 test_155e() {
12752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12753
12754         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12755
12756         save_writethrough $p
12757
12758         set_cache read on
12759         set_cache writethrough on
12760         test_155_big_load
12761         restore_lustre_params < $p
12762         rm -f $p
12763 }
12764 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12765
12766 test_155f() {
12767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12768
12769         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12770
12771         save_writethrough $p
12772
12773         set_cache read on
12774         set_cache writethrough off
12775         test_155_big_load
12776         restore_lustre_params < $p
12777         rm -f $p
12778 }
12779 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12780
12781 test_155g() {
12782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12783
12784         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12785
12786         save_writethrough $p
12787
12788         set_cache read off
12789         set_cache writethrough on
12790         test_155_big_load
12791         restore_lustre_params < $p
12792         rm -f $p
12793 }
12794 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12795
12796 test_155h() {
12797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12798
12799         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12800
12801         save_writethrough $p
12802
12803         set_cache read off
12804         set_cache writethrough off
12805         test_155_big_load
12806         restore_lustre_params < $p
12807         rm -f $p
12808 }
12809 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12810
12811 test_156() {
12812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12813         remote_ost_nodsh && skip "remote OST with nodsh"
12814         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12815                 skip "stats not implemented on old servers"
12816         [ "$ost1_FSTYPE" = "zfs" ] &&
12817                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12818
12819         local CPAGES=3
12820         local BEFORE
12821         local AFTER
12822         local file="$DIR/$tfile"
12823         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12824
12825         save_writethrough $p
12826         roc_hit_init
12827
12828         log "Turn on read and write cache"
12829         set_cache read on
12830         set_cache writethrough on
12831
12832         log "Write data and read it back."
12833         log "Read should be satisfied from the cache."
12834         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12835         BEFORE=$(roc_hit)
12836         cancel_lru_locks osc
12837         cat $file >/dev/null
12838         AFTER=$(roc_hit)
12839         if ! let "AFTER - BEFORE == CPAGES"; then
12840                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12841         else
12842                 log "cache hits:: before: $BEFORE, after: $AFTER"
12843         fi
12844
12845         log "Read again; it should be satisfied from the cache."
12846         BEFORE=$AFTER
12847         cancel_lru_locks osc
12848         cat $file >/dev/null
12849         AFTER=$(roc_hit)
12850         if ! let "AFTER - BEFORE == CPAGES"; then
12851                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12852         else
12853                 log "cache hits:: before: $BEFORE, after: $AFTER"
12854         fi
12855
12856         log "Turn off the read cache and turn on the write cache"
12857         set_cache read off
12858         set_cache writethrough on
12859
12860         log "Read again; it should be satisfied from the cache."
12861         BEFORE=$(roc_hit)
12862         cancel_lru_locks osc
12863         cat $file >/dev/null
12864         AFTER=$(roc_hit)
12865         if ! let "AFTER - BEFORE == CPAGES"; then
12866                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12867         else
12868                 log "cache hits:: before: $BEFORE, after: $AFTER"
12869         fi
12870
12871         log "Read again; it should not be satisfied from the cache."
12872         BEFORE=$AFTER
12873         cancel_lru_locks osc
12874         cat $file >/dev/null
12875         AFTER=$(roc_hit)
12876         if ! let "AFTER - BEFORE == 0"; then
12877                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12878         else
12879                 log "cache hits:: before: $BEFORE, after: $AFTER"
12880         fi
12881
12882         log "Write data and read it back."
12883         log "Read should be satisfied from the cache."
12884         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12885         BEFORE=$(roc_hit)
12886         cancel_lru_locks osc
12887         cat $file >/dev/null
12888         AFTER=$(roc_hit)
12889         if ! let "AFTER - BEFORE == CPAGES"; then
12890                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12891         else
12892                 log "cache hits:: before: $BEFORE, after: $AFTER"
12893         fi
12894
12895         log "Read again; it should not be satisfied from the cache."
12896         BEFORE=$AFTER
12897         cancel_lru_locks osc
12898         cat $file >/dev/null
12899         AFTER=$(roc_hit)
12900         if ! let "AFTER - BEFORE == 0"; then
12901                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12902         else
12903                 log "cache hits:: before: $BEFORE, after: $AFTER"
12904         fi
12905
12906         log "Turn off read and write cache"
12907         set_cache read off
12908         set_cache writethrough off
12909
12910         log "Write data and read it back"
12911         log "It should not be satisfied from the cache."
12912         rm -f $file
12913         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12914         cancel_lru_locks osc
12915         BEFORE=$(roc_hit)
12916         cat $file >/dev/null
12917         AFTER=$(roc_hit)
12918         if ! let "AFTER - BEFORE == 0"; then
12919                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12920         else
12921                 log "cache hits:: before: $BEFORE, after: $AFTER"
12922         fi
12923
12924         log "Turn on the read cache and turn off the write cache"
12925         set_cache read on
12926         set_cache writethrough off
12927
12928         log "Write data and read it back"
12929         log "It should not be satisfied from the cache."
12930         rm -f $file
12931         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12932         BEFORE=$(roc_hit)
12933         cancel_lru_locks osc
12934         cat $file >/dev/null
12935         AFTER=$(roc_hit)
12936         if ! let "AFTER - BEFORE == 0"; then
12937                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12938         else
12939                 log "cache hits:: before: $BEFORE, after: $AFTER"
12940         fi
12941
12942         log "Read again; it should be satisfied from the cache."
12943         BEFORE=$(roc_hit)
12944         cancel_lru_locks osc
12945         cat $file >/dev/null
12946         AFTER=$(roc_hit)
12947         if ! let "AFTER - BEFORE == CPAGES"; then
12948                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12949         else
12950                 log "cache hits:: before: $BEFORE, after: $AFTER"
12951         fi
12952
12953         restore_lustre_params < $p
12954         rm -f $p $file
12955 }
12956 run_test 156 "Verification of tunables"
12957
12958 test_160a() {
12959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12960         remote_mds_nodsh && skip "remote MDS with nodsh"
12961         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12962                 skip "Need MDS version at least 2.2.0"
12963
12964         changelog_register || error "changelog_register failed"
12965         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12966         changelog_users $SINGLEMDS | grep -q $cl_user ||
12967                 error "User $cl_user not found in changelog_users"
12968
12969         # change something
12970         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12971         changelog_clear 0 || error "changelog_clear failed"
12972         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12973         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12974         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12975         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12976         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12977         rm $DIR/$tdir/pics/desktop.jpg
12978
12979         changelog_dump | tail -10
12980
12981         echo "verifying changelog mask"
12982         changelog_chmask "-MKDIR"
12983         changelog_chmask "-CLOSE"
12984
12985         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12986         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12987
12988         changelog_chmask "+MKDIR"
12989         changelog_chmask "+CLOSE"
12990
12991         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12992         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12993
12994         changelog_dump | tail -10
12995         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12996         CLOSES=$(changelog_dump | grep -c "CLOSE")
12997         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12998         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12999
13000         # verify contents
13001         echo "verifying target fid"
13002         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13003         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13004         [ "$fidc" == "$fidf" ] ||
13005                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13006         echo "verifying parent fid"
13007         # The FID returned from the Changelog may be the directory shard on
13008         # a different MDT, and not the FID returned by path2fid on the parent.
13009         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13010         # since this is what will matter when recreating this file in the tree.
13011         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13012         local pathp=$($LFS fid2path $MOUNT "$fidp")
13013         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13014                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13015
13016         echo "getting records for $cl_user"
13017         changelog_users $SINGLEMDS
13018         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13019         local nclr=3
13020         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13021                 error "changelog_clear failed"
13022         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13023         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13024         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13025                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13026
13027         local min0_rec=$(changelog_users $SINGLEMDS |
13028                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13029         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13030                           awk '{ print $1; exit; }')
13031
13032         changelog_dump | tail -n 5
13033         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13034         [ $first_rec == $((min0_rec + 1)) ] ||
13035                 error "first index should be $min0_rec + 1 not $first_rec"
13036
13037         # LU-3446 changelog index reset on MDT restart
13038         local cur_rec1=$(changelog_users $SINGLEMDS |
13039                          awk '/^current.index:/ { print $NF }')
13040         changelog_clear 0 ||
13041                 error "clear all changelog records for $cl_user failed"
13042         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13043         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13044                 error "Fail to start $SINGLEMDS"
13045         local cur_rec2=$(changelog_users $SINGLEMDS |
13046                          awk '/^current.index:/ { print $NF }')
13047         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13048         [ $cur_rec1 == $cur_rec2 ] ||
13049                 error "current index should be $cur_rec1 not $cur_rec2"
13050
13051         echo "verifying users from this test are deregistered"
13052         changelog_deregister || error "changelog_deregister failed"
13053         changelog_users $SINGLEMDS | grep -q $cl_user &&
13054                 error "User '$cl_user' still in changelog_users"
13055
13056         # lctl get_param -n mdd.*.changelog_users
13057         # current index: 144
13058         # ID    index (idle seconds)
13059         # cl3   144 (2)
13060         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13061                 # this is the normal case where all users were deregistered
13062                 # make sure no new records are added when no users are present
13063                 local last_rec1=$(changelog_users $SINGLEMDS |
13064                                   awk '/^current.index:/ { print $NF }')
13065                 touch $DIR/$tdir/chloe
13066                 local last_rec2=$(changelog_users $SINGLEMDS |
13067                                   awk '/^current.index:/ { print $NF }')
13068                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13069                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13070         else
13071                 # any changelog users must be leftovers from a previous test
13072                 changelog_users $SINGLEMDS
13073                 echo "other changelog users; can't verify off"
13074         fi
13075 }
13076 run_test 160a "changelog sanity"
13077
13078 test_160b() { # LU-3587
13079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13080         remote_mds_nodsh && skip "remote MDS with nodsh"
13081         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13082                 skip "Need MDS version at least 2.2.0"
13083
13084         changelog_register || error "changelog_register failed"
13085         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13086         changelog_users $SINGLEMDS | grep -q $cl_user ||
13087                 error "User '$cl_user' not found in changelog_users"
13088
13089         local longname1=$(str_repeat a 255)
13090         local longname2=$(str_repeat b 255)
13091
13092         cd $DIR
13093         echo "creating very long named file"
13094         touch $longname1 || error "create of '$longname1' failed"
13095         echo "renaming very long named file"
13096         mv $longname1 $longname2
13097
13098         changelog_dump | grep RENME | tail -n 5
13099         rm -f $longname2
13100 }
13101 run_test 160b "Verify that very long rename doesn't crash in changelog"
13102
13103 test_160c() {
13104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13105         remote_mds_nodsh && skip "remote MDS with nodsh"
13106
13107         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13108                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13109                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13110                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13111
13112         local rc=0
13113
13114         # Registration step
13115         changelog_register || error "changelog_register failed"
13116
13117         rm -rf $DIR/$tdir
13118         mkdir -p $DIR/$tdir
13119         $MCREATE $DIR/$tdir/foo_160c
13120         changelog_chmask "-TRUNC"
13121         $TRUNCATE $DIR/$tdir/foo_160c 200
13122         changelog_chmask "+TRUNC"
13123         $TRUNCATE $DIR/$tdir/foo_160c 199
13124         changelog_dump | tail -n 5
13125         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13126         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13127 }
13128 run_test 160c "verify that changelog log catch the truncate event"
13129
13130 test_160d() {
13131         remote_mds_nodsh && skip "remote MDS with nodsh"
13132         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13134         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13135                 skip "Need MDS version at least 2.7.60"
13136
13137         # Registration step
13138         changelog_register || error "changelog_register failed"
13139
13140         mkdir -p $DIR/$tdir/migrate_dir
13141         changelog_clear 0 || error "changelog_clear failed"
13142
13143         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13144         changelog_dump | tail -n 5
13145         local migrates=$(changelog_dump | grep -c "MIGRT")
13146         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13147 }
13148 run_test 160d "verify that changelog log catch the migrate event"
13149
13150 test_160e() {
13151         remote_mds_nodsh && skip "remote MDS with nodsh"
13152
13153         # Create a user
13154         changelog_register || error "changelog_register failed"
13155
13156         # Delete a future user (expect fail)
13157         local MDT0=$(facet_svc $SINGLEMDS)
13158         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13159         local rc=$?
13160
13161         if [ $rc -eq 0 ]; then
13162                 error "Deleted non-existant user cl77"
13163         elif [ $rc -ne 2 ]; then
13164                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13165         fi
13166
13167         # Clear to a bad index (1 billion should be safe)
13168         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13169         rc=$?
13170
13171         if [ $rc -eq 0 ]; then
13172                 error "Successfully cleared to invalid CL index"
13173         elif [ $rc -ne 22 ]; then
13174                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13175         fi
13176 }
13177 run_test 160e "changelog negative testing (should return errors)"
13178
13179 test_160f() {
13180         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13181         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13182                 skip "Need MDS version at least 2.10.56"
13183
13184         local mdts=$(comma_list $(mdts_nodes))
13185
13186         # Create a user
13187         changelog_register || error "first changelog_register failed"
13188         changelog_register || error "second changelog_register failed"
13189         local cl_users
13190         declare -A cl_user1
13191         declare -A cl_user2
13192         local user_rec1
13193         local user_rec2
13194         local i
13195
13196         # generate some changelog records to accumulate on each MDT
13197         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13198         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13199                 error "create $DIR/$tdir/$tfile failed"
13200
13201         # check changelogs have been generated
13202         local nbcl=$(changelog_dump | wc -l)
13203         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13204
13205         for param in "changelog_max_idle_time=10" \
13206                      "changelog_gc=1" \
13207                      "changelog_min_gc_interval=2" \
13208                      "changelog_min_free_cat_entries=3"; do
13209                 local MDT0=$(facet_svc $SINGLEMDS)
13210                 local var="${param%=*}"
13211                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13212
13213                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13214                 do_nodes $mdts $LCTL set_param mdd.*.$param
13215         done
13216
13217         # force cl_user2 to be idle (1st part)
13218         sleep 9
13219
13220         # simulate changelog catalog almost full
13221         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13222         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13223
13224         for i in $(seq $MDSCOUNT); do
13225                 cl_users=(${CL_USERS[mds$i]})
13226                 cl_user1[mds$i]="${cl_users[0]}"
13227                 cl_user2[mds$i]="${cl_users[1]}"
13228
13229                 [ -n "${cl_user1[mds$i]}" ] ||
13230                         error "mds$i: no user registered"
13231                 [ -n "${cl_user2[mds$i]}" ] ||
13232                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13233
13234                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13235                 [ -n "$user_rec1" ] ||
13236                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13237                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13238                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13239                 [ -n "$user_rec2" ] ||
13240                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13241                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13242                      "$user_rec1 + 2 == $user_rec2"
13243                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13244                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13245                               "$user_rec1 + 2, but is $user_rec2"
13246                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13247                 [ -n "$user_rec2" ] ||
13248                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13249                 [ $user_rec1 == $user_rec2 ] ||
13250                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13251                               "$user_rec1, but is $user_rec2"
13252         done
13253
13254         # force cl_user2 to be idle (2nd part) and to reach
13255         # changelog_max_idle_time
13256         sleep 2
13257
13258         # generate one more changelog to trigger fail_loc
13259         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13260                 error "create $DIR/$tdir/${tfile}bis failed"
13261
13262         # ensure gc thread is done
13263         for i in $(mdts_nodes); do
13264                 wait_update $i \
13265                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13266                         error "$i: GC-thread not done"
13267         done
13268
13269         local first_rec
13270         for i in $(seq $MDSCOUNT); do
13271                 # check cl_user1 still registered
13272                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13273                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13274                 # check cl_user2 unregistered
13275                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13276                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13277
13278                 # check changelogs are present and starting at $user_rec1 + 1
13279                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13280                 [ -n "$user_rec1" ] ||
13281                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13282                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13283                             awk '{ print $1; exit; }')
13284
13285                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13286                 [ $((user_rec1 + 1)) == $first_rec ] ||
13287                         error "mds$i: first index should be $user_rec1 + 1, " \
13288                               "but is $first_rec"
13289         done
13290 }
13291 run_test 160f "changelog garbage collect (timestamped users)"
13292
13293 test_160g() {
13294         remote_mds_nodsh && skip "remote MDS with nodsh"
13295         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13296                 skip "Need MDS version at least 2.10.56"
13297
13298         local mdts=$(comma_list $(mdts_nodes))
13299
13300         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13301         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13302
13303         # Create a user
13304         changelog_register || error "first changelog_register failed"
13305         changelog_register || error "second changelog_register failed"
13306         local cl_users
13307         declare -A cl_user1
13308         declare -A cl_user2
13309         local user_rec1
13310         local user_rec2
13311         local i
13312
13313         # generate some changelog records to accumulate on each MDT
13314         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13315         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13316                 error "create $DIR/$tdir/$tfile failed"
13317
13318         # check changelogs have been generated
13319         local nbcl=$(changelog_dump | wc -l)
13320         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13321
13322         # reduce the max_idle_indexes value to make sure we exceed it
13323         max_ndx=$((nbcl / 2 - 1))
13324
13325         for param in "changelog_max_idle_indexes=$max_ndx" \
13326                      "changelog_gc=1" \
13327                      "changelog_min_gc_interval=2" \
13328                      "changelog_min_free_cat_entries=3"; do
13329                 local MDT0=$(facet_svc $SINGLEMDS)
13330                 local var="${param%=*}"
13331                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13332
13333                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13334                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13335                         error "unable to set mdd.*.$param"
13336         done
13337
13338         # simulate changelog catalog almost full
13339         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13340         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13341
13342         for i in $(seq $MDSCOUNT); do
13343                 cl_users=(${CL_USERS[mds$i]})
13344                 cl_user1[mds$i]="${cl_users[0]}"
13345                 cl_user2[mds$i]="${cl_users[1]}"
13346
13347                 [ -n "${cl_user1[mds$i]}" ] ||
13348                         error "mds$i: no user registered"
13349                 [ -n "${cl_user2[mds$i]}" ] ||
13350                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13351
13352                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13353                 [ -n "$user_rec1" ] ||
13354                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13355                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13356                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13357                 [ -n "$user_rec2" ] ||
13358                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13359                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13360                      "$user_rec1 + 2 == $user_rec2"
13361                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13362                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13363                               "$user_rec1 + 2, but is $user_rec2"
13364                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13365                 [ -n "$user_rec2" ] ||
13366                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13367                 [ $user_rec1 == $user_rec2 ] ||
13368                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13369                               "$user_rec1, but is $user_rec2"
13370         done
13371
13372         # ensure we are past the previous changelog_min_gc_interval set above
13373         sleep 2
13374
13375         # generate one more changelog to trigger fail_loc
13376         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13377                 error "create $DIR/$tdir/${tfile}bis failed"
13378
13379         # ensure gc thread is done
13380         for i in $(mdts_nodes); do
13381                 wait_update $i \
13382                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13383                         error "$i: GC-thread not done"
13384         done
13385
13386         local first_rec
13387         for i in $(seq $MDSCOUNT); do
13388                 # check cl_user1 still registered
13389                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13390                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13391                 # check cl_user2 unregistered
13392                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13393                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13394
13395                 # check changelogs are present and starting at $user_rec1 + 1
13396                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13397                 [ -n "$user_rec1" ] ||
13398                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13399                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13400                             awk '{ print $1; exit; }')
13401
13402                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13403                 [ $((user_rec1 + 1)) == $first_rec ] ||
13404                         error "mds$i: first index should be $user_rec1 + 1, " \
13405                               "but is $first_rec"
13406         done
13407 }
13408 run_test 160g "changelog garbage collect (old users)"
13409
13410 test_160h() {
13411         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13412         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13413                 skip "Need MDS version at least 2.10.56"
13414
13415         local mdts=$(comma_list $(mdts_nodes))
13416
13417         # Create a user
13418         changelog_register || error "first changelog_register failed"
13419         changelog_register || error "second changelog_register failed"
13420         local cl_users
13421         declare -A cl_user1
13422         declare -A cl_user2
13423         local user_rec1
13424         local user_rec2
13425         local i
13426
13427         # generate some changelog records to accumulate on each MDT
13428         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13429         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13430                 error "create $DIR/$tdir/$tfile failed"
13431
13432         # check changelogs have been generated
13433         local nbcl=$(changelog_dump | wc -l)
13434         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13435
13436         for param in "changelog_max_idle_time=10" \
13437                      "changelog_gc=1" \
13438                      "changelog_min_gc_interval=2"; do
13439                 local MDT0=$(facet_svc $SINGLEMDS)
13440                 local var="${param%=*}"
13441                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13442
13443                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13444                 do_nodes $mdts $LCTL set_param mdd.*.$param
13445         done
13446
13447         # force cl_user2 to be idle (1st part)
13448         sleep 9
13449
13450         for i in $(seq $MDSCOUNT); do
13451                 cl_users=(${CL_USERS[mds$i]})
13452                 cl_user1[mds$i]="${cl_users[0]}"
13453                 cl_user2[mds$i]="${cl_users[1]}"
13454
13455                 [ -n "${cl_user1[mds$i]}" ] ||
13456                         error "mds$i: no user registered"
13457                 [ -n "${cl_user2[mds$i]}" ] ||
13458                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13459
13460                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13461                 [ -n "$user_rec1" ] ||
13462                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13463                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13464                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13465                 [ -n "$user_rec2" ] ||
13466                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13467                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13468                      "$user_rec1 + 2 == $user_rec2"
13469                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13470                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13471                               "$user_rec1 + 2, but is $user_rec2"
13472                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13473                 [ -n "$user_rec2" ] ||
13474                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13475                 [ $user_rec1 == $user_rec2 ] ||
13476                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13477                               "$user_rec1, but is $user_rec2"
13478         done
13479
13480         # force cl_user2 to be idle (2nd part) and to reach
13481         # changelog_max_idle_time
13482         sleep 2
13483
13484         # force each GC-thread start and block then
13485         # one per MDT/MDD, set fail_val accordingly
13486         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
13487         do_nodes $mdts $LCTL set_param fail_loc=0x1316
13488
13489         # generate more changelogs to trigger fail_loc
13490         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13491                 error "create $DIR/$tdir/${tfile}bis failed"
13492
13493         # stop MDT to stop GC-thread, should be done in back-ground as it will
13494         # block waiting for the thread to be released and exit
13495         declare -A stop_pids
13496         for i in $(seq $MDSCOUNT); do
13497                 stop mds$i &
13498                 stop_pids[mds$i]=$!
13499         done
13500
13501         for i in $(mdts_nodes); do
13502                 local facet
13503                 local nb=0
13504                 local facets=$(facets_up_on_host $i)
13505
13506                 for facet in ${facets//,/ }; do
13507                         if [[ $facet == mds* ]]; then
13508                                 nb=$((nb + 1))
13509                         fi
13510                 done
13511                 # ensure each MDS's gc threads are still present and all in "R"
13512                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
13513                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
13514                         error "$i: expected $nb GC-thread"
13515                 wait_update $i \
13516                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
13517                         "R" 20 ||
13518                         error "$i: GC-thread not found in R-state"
13519                 # check umounts of each MDT on MDS have reached kthread_stop()
13520                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
13521                         error "$i: expected $nb umount"
13522                 wait_update $i \
13523                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
13524                         error "$i: umount not found in D-state"
13525         done
13526
13527         # release all GC-threads
13528         do_nodes $mdts $LCTL set_param fail_loc=0
13529
13530         # wait for MDT stop to complete
13531         for i in $(seq $MDSCOUNT); do
13532                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13533         done
13534
13535         # XXX
13536         # may try to check if any orphan changelog records are present
13537         # via ldiskfs/zfs and llog_reader...
13538
13539         # re-start/mount MDTs
13540         for i in $(seq $MDSCOUNT); do
13541                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13542                         error "Fail to start mds$i"
13543         done
13544
13545         local first_rec
13546         for i in $(seq $MDSCOUNT); do
13547                 # check cl_user1 still registered
13548                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13549                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13550                 # check cl_user2 unregistered
13551                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13552                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13553
13554                 # check changelogs are present and starting at $user_rec1 + 1
13555                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13556                 [ -n "$user_rec1" ] ||
13557                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13558                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13559                             awk '{ print $1; exit; }')
13560
13561                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13562                 [ $((user_rec1 + 1)) == $first_rec ] ||
13563                         error "mds$i: first index should be $user_rec1 + 1, " \
13564                               "but is $first_rec"
13565         done
13566 }
13567 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13568               "during mount"
13569
13570 test_160i() {
13571
13572         local mdts=$(comma_list $(mdts_nodes))
13573
13574         changelog_register || error "first changelog_register failed"
13575
13576         # generate some changelog records to accumulate on each MDT
13577         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13578         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13579                 error "create $DIR/$tdir/$tfile failed"
13580
13581         # check changelogs have been generated
13582         local nbcl=$(changelog_dump | wc -l)
13583         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13584
13585         # simulate race between register and unregister
13586         # XXX as fail_loc is set per-MDS, with DNE configs the race
13587         # simulation will only occur for one MDT per MDS and for the
13588         # others the normal race scenario will take place
13589         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13590         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13591         do_nodes $mdts $LCTL set_param fail_val=1
13592
13593         # unregister 1st user
13594         changelog_deregister &
13595         local pid1=$!
13596         # wait some time for deregister work to reach race rdv
13597         sleep 2
13598         # register 2nd user
13599         changelog_register || error "2nd user register failed"
13600
13601         wait $pid1 || error "1st user deregister failed"
13602
13603         local i
13604         local last_rec
13605         declare -A LAST_REC
13606         for i in $(seq $MDSCOUNT); do
13607                 if changelog_users mds$i | grep "^cl"; then
13608                         # make sure new records are added with one user present
13609                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13610                                           awk '/^current.index:/ { print $NF }')
13611                 else
13612                         error "mds$i has no user registered"
13613                 fi
13614         done
13615
13616         # generate more changelog records to accumulate on each MDT
13617         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13618                 error "create $DIR/$tdir/${tfile}bis failed"
13619
13620         for i in $(seq $MDSCOUNT); do
13621                 last_rec=$(changelog_users $SINGLEMDS |
13622                            awk '/^current.index:/ { print $NF }')
13623                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13624                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13625                         error "changelogs are off on mds$i"
13626         done
13627 }
13628 run_test 160i "changelog user register/unregister race"
13629
13630 test_161a() {
13631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13632
13633         test_mkdir -c1 $DIR/$tdir
13634         cp /etc/hosts $DIR/$tdir/$tfile
13635         test_mkdir -c1 $DIR/$tdir/foo1
13636         test_mkdir -c1 $DIR/$tdir/foo2
13637         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13638         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13639         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13640         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13641         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13642         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13643                 $LFS fid2path $DIR $FID
13644                 error "bad link ea"
13645         fi
13646         # middle
13647         rm $DIR/$tdir/foo2/zachary
13648         # last
13649         rm $DIR/$tdir/foo2/thor
13650         # first
13651         rm $DIR/$tdir/$tfile
13652         # rename
13653         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13654         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13655                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13656         rm $DIR/$tdir/foo2/maggie
13657
13658         # overflow the EA
13659         local longname=$tfile.avg_len_is_thirty_two_
13660         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13661                 error_noexit 'failed to unlink many hardlinks'" EXIT
13662         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13663                 error "failed to hardlink many files"
13664         links=$($LFS fid2path $DIR $FID | wc -l)
13665         echo -n "${links}/1000 links in link EA"
13666         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13667 }
13668 run_test 161a "link ea sanity"
13669
13670 test_161b() {
13671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13672         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13673
13674         local MDTIDX=1
13675         local remote_dir=$DIR/$tdir/remote_dir
13676
13677         mkdir -p $DIR/$tdir
13678         $LFS mkdir -i $MDTIDX $remote_dir ||
13679                 error "create remote directory failed"
13680
13681         cp /etc/hosts $remote_dir/$tfile
13682         mkdir -p $remote_dir/foo1
13683         mkdir -p $remote_dir/foo2
13684         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13685         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13686         ln $remote_dir/$tfile $remote_dir/foo1/luna
13687         ln $remote_dir/$tfile $remote_dir/foo2/thor
13688
13689         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13690                      tr -d ']')
13691         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13692                 $LFS fid2path $DIR $FID
13693                 error "bad link ea"
13694         fi
13695         # middle
13696         rm $remote_dir/foo2/zachary
13697         # last
13698         rm $remote_dir/foo2/thor
13699         # first
13700         rm $remote_dir/$tfile
13701         # rename
13702         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13703         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13704         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13705                 $LFS fid2path $DIR $FID
13706                 error "bad link rename"
13707         fi
13708         rm $remote_dir/foo2/maggie
13709
13710         # overflow the EA
13711         local longname=filename_avg_len_is_thirty_two_
13712         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13713                 error "failed to hardlink many files"
13714         links=$($LFS fid2path $DIR $FID | wc -l)
13715         echo -n "${links}/1000 links in link EA"
13716         [[ ${links} -gt 60 ]] ||
13717                 error "expected at least 60 links in link EA"
13718         unlinkmany $remote_dir/foo2/$longname 1000 ||
13719         error "failed to unlink many hardlinks"
13720 }
13721 run_test 161b "link ea sanity under remote directory"
13722
13723 test_161c() {
13724         remote_mds_nodsh && skip "remote MDS with nodsh"
13725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13726         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13727                 skip "Need MDS version at least 2.1.5"
13728
13729         # define CLF_RENAME_LAST 0x0001
13730         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13731         changelog_register || error "changelog_register failed"
13732
13733         rm -rf $DIR/$tdir
13734         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13735         touch $DIR/$tdir/foo_161c
13736         touch $DIR/$tdir/bar_161c
13737         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13738         changelog_dump | grep RENME | tail -n 5
13739         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13740         changelog_clear 0 || error "changelog_clear failed"
13741         if [ x$flags != "x0x1" ]; then
13742                 error "flag $flags is not 0x1"
13743         fi
13744
13745         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13746         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13747         touch $DIR/$tdir/foo_161c
13748         touch $DIR/$tdir/bar_161c
13749         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13750         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13751         changelog_dump | grep RENME | tail -n 5
13752         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13753         changelog_clear 0 || error "changelog_clear failed"
13754         if [ x$flags != "x0x0" ]; then
13755                 error "flag $flags is not 0x0"
13756         fi
13757         echo "rename overwrite a target having nlink > 1," \
13758                 "changelog record has flags of $flags"
13759
13760         # rename doesn't overwrite a target (changelog flag 0x0)
13761         touch $DIR/$tdir/foo_161c
13762         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13763         changelog_dump | grep RENME | tail -n 5
13764         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13765         changelog_clear 0 || error "changelog_clear failed"
13766         if [ x$flags != "x0x0" ]; then
13767                 error "flag $flags is not 0x0"
13768         fi
13769         echo "rename doesn't overwrite a target," \
13770                 "changelog record has flags of $flags"
13771
13772         # define CLF_UNLINK_LAST 0x0001
13773         # unlink a file having nlink = 1 (changelog flag 0x1)
13774         rm -f $DIR/$tdir/foo2_161c
13775         changelog_dump | grep UNLNK | tail -n 5
13776         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13777         changelog_clear 0 || error "changelog_clear failed"
13778         if [ x$flags != "x0x1" ]; then
13779                 error "flag $flags is not 0x1"
13780         fi
13781         echo "unlink a file having nlink = 1," \
13782                 "changelog record has flags of $flags"
13783
13784         # unlink a file having nlink > 1 (changelog flag 0x0)
13785         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13786         rm -f $DIR/$tdir/foobar_161c
13787         changelog_dump | grep UNLNK | tail -n 5
13788         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13789         changelog_clear 0 || error "changelog_clear failed"
13790         if [ x$flags != "x0x0" ]; then
13791                 error "flag $flags is not 0x0"
13792         fi
13793         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13794 }
13795 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13796
13797 test_161d() {
13798         remote_mds_nodsh && skip "remote MDS with nodsh"
13799         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13800
13801         local pid
13802         local fid
13803
13804         changelog_register || error "changelog_register failed"
13805
13806         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13807         # interfer with $MOUNT/.lustre/fid/ access
13808         mkdir $DIR/$tdir
13809         [[ $? -eq 0 ]] || error "mkdir failed"
13810
13811         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13812         $LCTL set_param fail_loc=0x8000140c
13813         # 5s pause
13814         $LCTL set_param fail_val=5
13815
13816         # create file
13817         echo foofoo > $DIR/$tdir/$tfile &
13818         pid=$!
13819
13820         # wait for create to be delayed
13821         sleep 2
13822
13823         ps -p $pid
13824         [[ $? -eq 0 ]] || error "create should be blocked"
13825
13826         local tempfile=$(mktemp)
13827         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13828         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13829         # some delay may occur during ChangeLog publishing and file read just
13830         # above, that could allow file write to happen finally
13831         [[ -s $tempfile ]] && echo "file should be empty"
13832
13833         $LCTL set_param fail_loc=0
13834
13835         wait $pid
13836         [[ $? -eq 0 ]] || error "create failed"
13837 }
13838 run_test 161d "create with concurrent .lustre/fid access"
13839
13840 check_path() {
13841         local expected="$1"
13842         shift
13843         local fid="$2"
13844
13845         local path
13846         path=$($LFS fid2path "$@")
13847         local rc=$?
13848
13849         if [ $rc -ne 0 ]; then
13850                 error "path looked up of '$expected' failed: rc=$rc"
13851         elif [ "$path" != "$expected" ]; then
13852                 error "path looked up '$path' instead of '$expected'"
13853         else
13854                 echo "FID '$fid' resolves to path '$path' as expected"
13855         fi
13856 }
13857
13858 test_162a() { # was test_162
13859         test_mkdir -p -c1 $DIR/$tdir/d2
13860         touch $DIR/$tdir/d2/$tfile
13861         touch $DIR/$tdir/d2/x1
13862         touch $DIR/$tdir/d2/x2
13863         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13864         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13865         # regular file
13866         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13867         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13868
13869         # softlink
13870         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13871         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13872         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13873
13874         # softlink to wrong file
13875         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13876         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13877         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13878
13879         # hardlink
13880         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13881         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13882         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13883         # fid2path dir/fsname should both work
13884         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13885         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13886
13887         # hardlink count: check that there are 2 links
13888         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13889         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13890
13891         # hardlink indexing: remove the first link
13892         rm $DIR/$tdir/d2/p/q/r/hlink
13893         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13894 }
13895 run_test 162a "path lookup sanity"
13896
13897 test_162b() {
13898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13899         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13900
13901         mkdir $DIR/$tdir
13902         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13903                                 error "create striped dir failed"
13904
13905         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13906                                         tail -n 1 | awk '{print $2}')
13907         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13908
13909         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13910         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13911
13912         # regular file
13913         for ((i=0;i<5;i++)); do
13914                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13915                         error "get fid for f$i failed"
13916                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13917
13918                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13919                         error "get fid for d$i failed"
13920                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13921         done
13922
13923         return 0
13924 }
13925 run_test 162b "striped directory path lookup sanity"
13926
13927 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13928 test_162c() {
13929         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13930                 skip "Need MDS version at least 2.7.51"
13931
13932         local lpath=$tdir.local
13933         local rpath=$tdir.remote
13934
13935         test_mkdir $DIR/$lpath
13936         test_mkdir $DIR/$rpath
13937
13938         for ((i = 0; i <= 101; i++)); do
13939                 lpath="$lpath/$i"
13940                 mkdir $DIR/$lpath
13941                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13942                         error "get fid for local directory $DIR/$lpath failed"
13943                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13944
13945                 rpath="$rpath/$i"
13946                 test_mkdir $DIR/$rpath
13947                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13948                         error "get fid for remote directory $DIR/$rpath failed"
13949                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13950         done
13951
13952         return 0
13953 }
13954 run_test 162c "fid2path works with paths 100 or more directories deep"
13955
13956 test_169() {
13957         # do directio so as not to populate the page cache
13958         log "creating a 10 Mb file"
13959         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13960         log "starting reads"
13961         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13962         log "truncating the file"
13963         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13964         log "killing dd"
13965         kill %+ || true # reads might have finished
13966         echo "wait until dd is finished"
13967         wait
13968         log "removing the temporary file"
13969         rm -rf $DIR/$tfile || error "tmp file removal failed"
13970 }
13971 run_test 169 "parallel read and truncate should not deadlock"
13972
13973 test_170() {
13974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13975
13976         $LCTL clear     # bug 18514
13977         $LCTL debug_daemon start $TMP/${tfile}_log_good
13978         touch $DIR/$tfile
13979         $LCTL debug_daemon stop
13980         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13981                 error "sed failed to read log_good"
13982
13983         $LCTL debug_daemon start $TMP/${tfile}_log_good
13984         rm -rf $DIR/$tfile
13985         $LCTL debug_daemon stop
13986
13987         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13988                error "lctl df log_bad failed"
13989
13990         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13991         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13992
13993         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13994         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13995
13996         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13997                 error "bad_line good_line1 good_line2 are empty"
13998
13999         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14000         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14001         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14002
14003         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14004         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14005         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14006
14007         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14008                 error "bad_line_new good_line_new are empty"
14009
14010         local expected_good=$((good_line1 + good_line2*2))
14011
14012         rm -f $TMP/${tfile}*
14013         # LU-231, short malformed line may not be counted into bad lines
14014         if [ $bad_line -ne $bad_line_new ] &&
14015                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14016                 error "expected $bad_line bad lines, but got $bad_line_new"
14017                 return 1
14018         fi
14019
14020         if [ $expected_good -ne $good_line_new ]; then
14021                 error "expected $expected_good good lines, but got $good_line_new"
14022                 return 2
14023         fi
14024         true
14025 }
14026 run_test 170 "test lctl df to handle corrupted log ====================="
14027
14028 test_171() { # bug20592
14029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14030
14031         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
14032         $LCTL set_param fail_loc=0x50e
14033         $LCTL set_param fail_val=3000
14034         multiop_bg_pause $DIR/$tfile O_s || true
14035         local MULTIPID=$!
14036         kill -USR1 $MULTIPID
14037         # cause log dump
14038         sleep 3
14039         wait $MULTIPID
14040         if dmesg | grep "recursive fault"; then
14041                 error "caught a recursive fault"
14042         fi
14043         $LCTL set_param fail_loc=0
14044         true
14045 }
14046 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
14047
14048 # it would be good to share it with obdfilter-survey/iokit-libecho code
14049 setup_obdecho_osc () {
14050         local rc=0
14051         local ost_nid=$1
14052         local obdfilter_name=$2
14053         echo "Creating new osc for $obdfilter_name on $ost_nid"
14054         # make sure we can find loopback nid
14055         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
14056
14057         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
14058                            ${obdfilter_name}_osc_UUID || rc=2; }
14059         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
14060                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
14061         return $rc
14062 }
14063
14064 cleanup_obdecho_osc () {
14065         local obdfilter_name=$1
14066         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14067         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14068         return 0
14069 }
14070
14071 obdecho_test() {
14072         local OBD=$1
14073         local node=$2
14074         local pages=${3:-64}
14075         local rc=0
14076         local id
14077
14078         local count=10
14079         local obd_size=$(get_obd_size $node $OBD)
14080         local page_size=$(get_page_size $node)
14081         if [[ -n "$obd_size" ]]; then
14082                 local new_count=$((obd_size / (pages * page_size / 1024)))
14083                 [[ $new_count -ge $count ]] || count=$new_count
14084         fi
14085
14086         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14087         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14088                            rc=2; }
14089         if [ $rc -eq 0 ]; then
14090             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14091             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14092         fi
14093         echo "New object id is $id"
14094         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14095                            rc=4; }
14096         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14097                            "test_brw $count w v $pages $id" || rc=4; }
14098         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14099                            rc=4; }
14100         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14101                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14102         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14103                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14104         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14105         return $rc
14106 }
14107
14108 test_180a() {
14109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14110
14111         if ! module_loaded obdecho; then
14112                 load_module obdecho/obdecho &&
14113                         stack_trap "rmmod obdecho" EXIT ||
14114                         error "unable to load obdecho on client"
14115         fi
14116
14117         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14118         local host=$($LCTL get_param -n osc.$osc.import |
14119                      awk '/current_connection:/ { print $2 }' )
14120         local target=$($LCTL get_param -n osc.$osc.import |
14121                        awk '/target:/ { print $2 }' )
14122         target=${target%_UUID}
14123
14124         if [ -n "$target" ]; then
14125                 setup_obdecho_osc $host $target &&
14126                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14127                         { error "obdecho setup failed with $?"; return; }
14128
14129                 obdecho_test ${target}_osc client ||
14130                         error "obdecho_test failed on ${target}_osc"
14131         else
14132                 $LCTL get_param osc.$osc.import
14133                 error "there is no osc.$osc.import target"
14134         fi
14135 }
14136 run_test 180a "test obdecho on osc"
14137
14138 test_180b() {
14139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14140         remote_ost_nodsh && skip "remote OST with nodsh"
14141
14142         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14143                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14144                 error "failed to load module obdecho"
14145
14146         local target=$(do_facet ost1 $LCTL dl |
14147                        awk '/obdfilter/ { print $4; exit; }')
14148
14149         if [ -n "$target" ]; then
14150                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14151         else
14152                 do_facet ost1 $LCTL dl
14153                 error "there is no obdfilter target on ost1"
14154         fi
14155 }
14156 run_test 180b "test obdecho directly on obdfilter"
14157
14158 test_180c() { # LU-2598
14159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14160         remote_ost_nodsh && skip "remote OST with nodsh"
14161         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14162                 skip "Need MDS version at least 2.4.0"
14163
14164         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14165                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14166                 error "failed to load module obdecho"
14167
14168         local target=$(do_facet ost1 $LCTL dl |
14169                        awk '/obdfilter/ { print $4; exit; }')
14170
14171         if [ -n "$target" ]; then
14172                 local pages=16384 # 64MB bulk I/O RPC size
14173
14174                 obdecho_test "$target" ost1 "$pages" ||
14175                         error "obdecho_test with pages=$pages failed with $?"
14176         else
14177                 do_facet ost1 $LCTL dl
14178                 error "there is no obdfilter target on ost1"
14179         fi
14180 }
14181 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14182
14183 test_181() { # bug 22177
14184         test_mkdir $DIR/$tdir
14185         # create enough files to index the directory
14186         createmany -o $DIR/$tdir/foobar 4000
14187         # print attributes for debug purpose
14188         lsattr -d .
14189         # open dir
14190         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14191         MULTIPID=$!
14192         # remove the files & current working dir
14193         unlinkmany $DIR/$tdir/foobar 4000
14194         rmdir $DIR/$tdir
14195         kill -USR1 $MULTIPID
14196         wait $MULTIPID
14197         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14198         return 0
14199 }
14200 run_test 181 "Test open-unlinked dir ========================"
14201
14202 test_182() {
14203         local fcount=1000
14204         local tcount=10
14205
14206         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14207
14208         $LCTL set_param mdc.*.rpc_stats=clear
14209
14210         for (( i = 0; i < $tcount; i++ )) ; do
14211                 mkdir $DIR/$tdir/$i
14212         done
14213
14214         for (( i = 0; i < $tcount; i++ )) ; do
14215                 createmany -o $DIR/$tdir/$i/f- $fcount &
14216         done
14217         wait
14218
14219         for (( i = 0; i < $tcount; i++ )) ; do
14220                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14221         done
14222         wait
14223
14224         $LCTL get_param mdc.*.rpc_stats
14225
14226         rm -rf $DIR/$tdir
14227 }
14228 run_test 182 "Test parallel modify metadata operations ================"
14229
14230 test_183() { # LU-2275
14231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14232         remote_mds_nodsh && skip "remote MDS with nodsh"
14233         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14234                 skip "Need MDS version at least 2.3.56"
14235
14236         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14237         echo aaa > $DIR/$tdir/$tfile
14238
14239 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14240         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14241
14242         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14243         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14244
14245         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14246
14247         # Flush negative dentry cache
14248         touch $DIR/$tdir/$tfile
14249
14250         # We are not checking for any leaked references here, they'll
14251         # become evident next time we do cleanup with module unload.
14252         rm -rf $DIR/$tdir
14253 }
14254 run_test 183 "No crash or request leak in case of strange dispositions ========"
14255
14256 # test suite 184 is for LU-2016, LU-2017
14257 test_184a() {
14258         check_swap_layouts_support
14259
14260         dir0=$DIR/$tdir/$testnum
14261         test_mkdir -p -c1 $dir0
14262         ref1=/etc/passwd
14263         ref2=/etc/group
14264         file1=$dir0/f1
14265         file2=$dir0/f2
14266         $LFS setstripe -c1 $file1
14267         cp $ref1 $file1
14268         $LFS setstripe -c2 $file2
14269         cp $ref2 $file2
14270         gen1=$($LFS getstripe -g $file1)
14271         gen2=$($LFS getstripe -g $file2)
14272
14273         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14274         gen=$($LFS getstripe -g $file1)
14275         [[ $gen1 != $gen ]] ||
14276                 "Layout generation on $file1 does not change"
14277         gen=$($LFS getstripe -g $file2)
14278         [[ $gen2 != $gen ]] ||
14279                 "Layout generation on $file2 does not change"
14280
14281         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14282         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14283
14284         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14285 }
14286 run_test 184a "Basic layout swap"
14287
14288 test_184b() {
14289         check_swap_layouts_support
14290
14291         dir0=$DIR/$tdir/$testnum
14292         mkdir -p $dir0 || error "creating dir $dir0"
14293         file1=$dir0/f1
14294         file2=$dir0/f2
14295         file3=$dir0/f3
14296         dir1=$dir0/d1
14297         dir2=$dir0/d2
14298         mkdir $dir1 $dir2
14299         $LFS setstripe -c1 $file1
14300         $LFS setstripe -c2 $file2
14301         $LFS setstripe -c1 $file3
14302         chown $RUNAS_ID $file3
14303         gen1=$($LFS getstripe -g $file1)
14304         gen2=$($LFS getstripe -g $file2)
14305
14306         $LFS swap_layouts $dir1 $dir2 &&
14307                 error "swap of directories layouts should fail"
14308         $LFS swap_layouts $dir1 $file1 &&
14309                 error "swap of directory and file layouts should fail"
14310         $RUNAS $LFS swap_layouts $file1 $file2 &&
14311                 error "swap of file we cannot write should fail"
14312         $LFS swap_layouts $file1 $file3 &&
14313                 error "swap of file with different owner should fail"
14314         /bin/true # to clear error code
14315 }
14316 run_test 184b "Forbidden layout swap (will generate errors)"
14317
14318 test_184c() {
14319         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14320         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14321         check_swap_layouts_support
14322
14323         local dir0=$DIR/$tdir/$testnum
14324         mkdir -p $dir0 || error "creating dir $dir0"
14325
14326         local ref1=$dir0/ref1
14327         local ref2=$dir0/ref2
14328         local file1=$dir0/file1
14329         local file2=$dir0/file2
14330         # create a file large enough for the concurrent test
14331         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14332         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14333         echo "ref file size: ref1($(stat -c %s $ref1))," \
14334              "ref2($(stat -c %s $ref2))"
14335
14336         cp $ref2 $file2
14337         dd if=$ref1 of=$file1 bs=16k &
14338         local DD_PID=$!
14339
14340         # Make sure dd starts to copy file
14341         while [ ! -f $file1 ]; do sleep 0.1; done
14342
14343         $LFS swap_layouts $file1 $file2
14344         local rc=$?
14345         wait $DD_PID
14346         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14347         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14348
14349         # how many bytes copied before swapping layout
14350         local copied=$(stat -c %s $file2)
14351         local remaining=$(stat -c %s $ref1)
14352         remaining=$((remaining - copied))
14353         echo "Copied $copied bytes before swapping layout..."
14354
14355         cmp -n $copied $file1 $ref2 | grep differ &&
14356                 error "Content mismatch [0, $copied) of ref2 and file1"
14357         cmp -n $copied $file2 $ref1 ||
14358                 error "Content mismatch [0, $copied) of ref1 and file2"
14359         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14360                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14361
14362         # clean up
14363         rm -f $ref1 $ref2 $file1 $file2
14364 }
14365 run_test 184c "Concurrent write and layout swap"
14366
14367 test_184d() {
14368         check_swap_layouts_support
14369         [ -z "$(which getfattr 2>/dev/null)" ] &&
14370                 skip_env "no getfattr command"
14371
14372         local file1=$DIR/$tdir/$tfile-1
14373         local file2=$DIR/$tdir/$tfile-2
14374         local file3=$DIR/$tdir/$tfile-3
14375         local lovea1
14376         local lovea2
14377
14378         mkdir -p $DIR/$tdir
14379         touch $file1 || error "create $file1 failed"
14380         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14381                 error "create $file2 failed"
14382         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14383                 error "create $file3 failed"
14384         lovea1=$(get_layout_param $file1)
14385
14386         $LFS swap_layouts $file2 $file3 ||
14387                 error "swap $file2 $file3 layouts failed"
14388         $LFS swap_layouts $file1 $file2 ||
14389                 error "swap $file1 $file2 layouts failed"
14390
14391         lovea2=$(get_layout_param $file2)
14392         echo "$lovea1"
14393         echo "$lovea2"
14394         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14395
14396         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14397         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14398 }
14399 run_test 184d "allow stripeless layouts swap"
14400
14401 test_184e() {
14402         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14403                 skip "Need MDS version at least 2.6.94"
14404         check_swap_layouts_support
14405         [ -z "$(which getfattr 2>/dev/null)" ] &&
14406                 skip_env "no getfattr command"
14407
14408         local file1=$DIR/$tdir/$tfile-1
14409         local file2=$DIR/$tdir/$tfile-2
14410         local file3=$DIR/$tdir/$tfile-3
14411         local lovea
14412
14413         mkdir -p $DIR/$tdir
14414         touch $file1 || error "create $file1 failed"
14415         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14416                 error "create $file2 failed"
14417         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14418                 error "create $file3 failed"
14419
14420         $LFS swap_layouts $file1 $file2 ||
14421                 error "swap $file1 $file2 layouts failed"
14422
14423         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14424         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
14425
14426         echo 123 > $file1 || error "Should be able to write into $file1"
14427
14428         $LFS swap_layouts $file1 $file3 ||
14429                 error "swap $file1 $file3 layouts failed"
14430
14431         echo 123 > $file1 || error "Should be able to write into $file1"
14432
14433         rm -rf $file1 $file2 $file3
14434 }
14435 run_test 184e "Recreate layout after stripeless layout swaps"
14436
14437 test_184f() {
14438         # Create a file with name longer than sizeof(struct stat) ==
14439         # 144 to see if we can get chars from the file name to appear
14440         # in the returned striping. Note that 'f' == 0x66.
14441         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
14442
14443         mkdir -p $DIR/$tdir
14444         mcreate $DIR/$tdir/$file
14445         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
14446                 error "IOC_MDC_GETFILEINFO returned garbage striping"
14447         fi
14448 }
14449 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
14450
14451 test_185() { # LU-2441
14452         # LU-3553 - no volatile file support in old servers
14453         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
14454                 skip "Need MDS version at least 2.3.60"
14455
14456         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14457         touch $DIR/$tdir/spoo
14458         local mtime1=$(stat -c "%Y" $DIR/$tdir)
14459         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
14460                 error "cannot create/write a volatile file"
14461         [ "$FILESET" == "" ] &&
14462         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
14463                 error "FID is still valid after close"
14464
14465         multiop_bg_pause $DIR/$tdir vVw4096_c
14466         local multi_pid=$!
14467
14468         local OLD_IFS=$IFS
14469         IFS=":"
14470         local fidv=($fid)
14471         IFS=$OLD_IFS
14472         # assume that the next FID for this client is sequential, since stdout
14473         # is unfortunately eaten by multiop_bg_pause
14474         local n=$((${fidv[1]} + 1))
14475         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
14476         if [ "$FILESET" == "" ]; then
14477                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
14478                         error "FID is missing before close"
14479         fi
14480         kill -USR1 $multi_pid
14481         # 1 second delay, so if mtime change we will see it
14482         sleep 1
14483         local mtime2=$(stat -c "%Y" $DIR/$tdir)
14484         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
14485 }
14486 run_test 185 "Volatile file support"
14487
14488 function create_check_volatile() {
14489         local idx=$1
14490         local tgt
14491
14492         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
14493         local PID=$!
14494         sleep 1
14495         local FID=$(cat /tmp/${tfile}.fid)
14496         [ "$FID" == "" ] && error "can't get FID for volatile"
14497         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
14498         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
14499         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
14500         kill -USR1 $PID
14501         wait
14502         sleep 1
14503         cancel_lru_locks mdc # flush opencache
14504         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
14505         return 0
14506 }
14507
14508 test_185a(){
14509         # LU-12516 - volatile creation via .lustre
14510         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
14511                 skip "Need MDS version at least 2.3.55"
14512
14513         create_check_volatile 0
14514         [ $MDSCOUNT -lt 2 ] && return 0
14515
14516         # DNE case
14517         create_check_volatile 1
14518
14519         return 0
14520 }
14521 run_test 185a "Volatile file creation in .lustre/fid/"
14522
14523 test_187a() {
14524         remote_mds_nodsh && skip "remote MDS with nodsh"
14525         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14526                 skip "Need MDS version at least 2.3.0"
14527
14528         local dir0=$DIR/$tdir/$testnum
14529         mkdir -p $dir0 || error "creating dir $dir0"
14530
14531         local file=$dir0/file1
14532         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
14533         local dv1=$($LFS data_version $file)
14534         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
14535         local dv2=$($LFS data_version $file)
14536         [[ $dv1 != $dv2 ]] ||
14537                 error "data version did not change on write $dv1 == $dv2"
14538
14539         # clean up
14540         rm -f $file1
14541 }
14542 run_test 187a "Test data version change"
14543
14544 test_187b() {
14545         remote_mds_nodsh && skip "remote MDS with nodsh"
14546         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14547                 skip "Need MDS version at least 2.3.0"
14548
14549         local dir0=$DIR/$tdir/$testnum
14550         mkdir -p $dir0 || error "creating dir $dir0"
14551
14552         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
14553         [[ ${DV[0]} != ${DV[1]} ]] ||
14554                 error "data version did not change on write"\
14555                       " ${DV[0]} == ${DV[1]}"
14556
14557         # clean up
14558         rm -f $file1
14559 }
14560 run_test 187b "Test data version change on volatile file"
14561
14562 test_200() {
14563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14564         remote_mgs_nodsh && skip "remote MGS with nodsh"
14565         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14566
14567         local POOL=${POOL:-cea1}
14568         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14569         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14570         # Pool OST targets
14571         local first_ost=0
14572         local last_ost=$(($OSTCOUNT - 1))
14573         local ost_step=2
14574         local ost_list=$(seq $first_ost $ost_step $last_ost)
14575         local ost_range="$first_ost $last_ost $ost_step"
14576         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14577         local file_dir=$POOL_ROOT/file_tst
14578         local subdir=$test_path/subdir
14579         local rc=0
14580
14581         if ! combined_mgs_mds ; then
14582                 mount_mgs_client
14583         fi
14584
14585         while : ; do
14586                 # former test_200a test_200b
14587                 pool_add $POOL                          || { rc=$? ; break; }
14588                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14589                 # former test_200c test_200d
14590                 mkdir -p $test_path
14591                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14592                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14593                 mkdir -p $subdir
14594                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14595                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14596                                                         || { rc=$? ; break; }
14597                 # former test_200e test_200f
14598                 local files=$((OSTCOUNT*3))
14599                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14600                                                         || { rc=$? ; break; }
14601                 pool_create_files $POOL $file_dir $files "$ost_list" \
14602                                                         || { rc=$? ; break; }
14603                 # former test_200g test_200h
14604                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14605                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14606
14607                 # former test_201a test_201b test_201c
14608                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14609
14610                 local f=$test_path/$tfile
14611                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14612                 pool_remove $POOL $f                    || { rc=$? ; break; }
14613                 break
14614         done
14615
14616         destroy_test_pools
14617
14618         if ! combined_mgs_mds ; then
14619                 umount_mgs_client
14620         fi
14621         return $rc
14622 }
14623 run_test 200 "OST pools"
14624
14625 # usage: default_attr <count | size | offset>
14626 default_attr() {
14627         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14628 }
14629
14630 # usage: check_default_stripe_attr
14631 check_default_stripe_attr() {
14632         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14633         case $1 in
14634         --stripe-count|-c)
14635                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14636         --stripe-size|-S)
14637                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14638         --stripe-index|-i)
14639                 EXPECTED=-1;;
14640         *)
14641                 error "unknown getstripe attr '$1'"
14642         esac
14643
14644         [ $ACTUAL == $EXPECTED ] ||
14645                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14646 }
14647
14648 test_204a() {
14649         test_mkdir $DIR/$tdir
14650         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14651
14652         check_default_stripe_attr --stripe-count
14653         check_default_stripe_attr --stripe-size
14654         check_default_stripe_attr --stripe-index
14655 }
14656 run_test 204a "Print default stripe attributes"
14657
14658 test_204b() {
14659         test_mkdir $DIR/$tdir
14660         $LFS setstripe --stripe-count 1 $DIR/$tdir
14661
14662         check_default_stripe_attr --stripe-size
14663         check_default_stripe_attr --stripe-index
14664 }
14665 run_test 204b "Print default stripe size and offset"
14666
14667 test_204c() {
14668         test_mkdir $DIR/$tdir
14669         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14670
14671         check_default_stripe_attr --stripe-count
14672         check_default_stripe_attr --stripe-index
14673 }
14674 run_test 204c "Print default stripe count and offset"
14675
14676 test_204d() {
14677         test_mkdir $DIR/$tdir
14678         $LFS setstripe --stripe-index 0 $DIR/$tdir
14679
14680         check_default_stripe_attr --stripe-count
14681         check_default_stripe_attr --stripe-size
14682 }
14683 run_test 204d "Print default stripe count and size"
14684
14685 test_204e() {
14686         test_mkdir $DIR/$tdir
14687         $LFS setstripe -d $DIR/$tdir
14688
14689         check_default_stripe_attr --stripe-count --raw
14690         check_default_stripe_attr --stripe-size --raw
14691         check_default_stripe_attr --stripe-index --raw
14692 }
14693 run_test 204e "Print raw stripe attributes"
14694
14695 test_204f() {
14696         test_mkdir $DIR/$tdir
14697         $LFS setstripe --stripe-count 1 $DIR/$tdir
14698
14699         check_default_stripe_attr --stripe-size --raw
14700         check_default_stripe_attr --stripe-index --raw
14701 }
14702 run_test 204f "Print raw stripe size and offset"
14703
14704 test_204g() {
14705         test_mkdir $DIR/$tdir
14706         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14707
14708         check_default_stripe_attr --stripe-count --raw
14709         check_default_stripe_attr --stripe-index --raw
14710 }
14711 run_test 204g "Print raw stripe count and offset"
14712
14713 test_204h() {
14714         test_mkdir $DIR/$tdir
14715         $LFS setstripe --stripe-index 0 $DIR/$tdir
14716
14717         check_default_stripe_attr --stripe-count --raw
14718         check_default_stripe_attr --stripe-size --raw
14719 }
14720 run_test 204h "Print raw stripe count and size"
14721
14722 # Figure out which job scheduler is being used, if any,
14723 # or use a fake one
14724 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14725         JOBENV=SLURM_JOB_ID
14726 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14727         JOBENV=LSB_JOBID
14728 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14729         JOBENV=PBS_JOBID
14730 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14731         JOBENV=LOADL_STEP_ID
14732 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14733         JOBENV=JOB_ID
14734 else
14735         $LCTL list_param jobid_name > /dev/null 2>&1
14736         if [ $? -eq 0 ]; then
14737                 JOBENV=nodelocal
14738         else
14739                 JOBENV=FAKE_JOBID
14740         fi
14741 fi
14742 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14743
14744 verify_jobstats() {
14745         local cmd=($1)
14746         shift
14747         local facets="$@"
14748
14749 # we don't really need to clear the stats for this test to work, since each
14750 # command has a unique jobid, but it makes debugging easier if needed.
14751 #       for facet in $facets; do
14752 #               local dev=$(convert_facet2label $facet)
14753 #               # clear old jobstats
14754 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14755 #       done
14756
14757         # use a new JobID for each test, or we might see an old one
14758         [ "$JOBENV" = "FAKE_JOBID" ] &&
14759                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14760
14761         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14762
14763         [ "$JOBENV" = "nodelocal" ] && {
14764                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14765                 $LCTL set_param jobid_name=$FAKE_JOBID
14766                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14767         }
14768
14769         log "Test: ${cmd[*]}"
14770         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14771
14772         if [ $JOBENV = "FAKE_JOBID" ]; then
14773                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14774         else
14775                 ${cmd[*]}
14776         fi
14777
14778         # all files are created on OST0000
14779         for facet in $facets; do
14780                 local stats="*.$(convert_facet2label $facet).job_stats"
14781
14782                 # strip out libtool wrappers for in-tree executables
14783                 if [ $(do_facet $facet lctl get_param $stats |
14784                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14785                         do_facet $facet lctl get_param $stats
14786                         error "No jobstats for $JOBVAL found on $facet::$stats"
14787                 fi
14788         done
14789 }
14790
14791 jobstats_set() {
14792         local new_jobenv=$1
14793
14794         set_persistent_param_and_check client "jobid_var" \
14795                 "$FSNAME.sys.jobid_var" $new_jobenv
14796 }
14797
14798 test_205() { # Job stats
14799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14800         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14801                 skip "Need MDS version with at least 2.7.1"
14802         remote_mgs_nodsh && skip "remote MGS with nodsh"
14803         remote_mds_nodsh && skip "remote MDS with nodsh"
14804         remote_ost_nodsh && skip "remote OST with nodsh"
14805         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14806                 skip "Server doesn't support jobstats"
14807         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14808
14809         local old_jobenv=$($LCTL get_param -n jobid_var)
14810         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14811
14812         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14813                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14814         else
14815                 stack_trap "do_facet mgs $PERM_CMD \
14816                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14817         fi
14818         changelog_register
14819
14820         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14821                                 mdt.*.job_cleanup_interval | head -n 1)
14822         local new_interval=5
14823         do_facet $SINGLEMDS \
14824                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14825         stack_trap "do_facet $SINGLEMDS \
14826                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14827         local start=$SECONDS
14828
14829         local cmd
14830         # mkdir
14831         cmd="mkdir $DIR/$tdir"
14832         verify_jobstats "$cmd" "$SINGLEMDS"
14833         # rmdir
14834         cmd="rmdir $DIR/$tdir"
14835         verify_jobstats "$cmd" "$SINGLEMDS"
14836         # mkdir on secondary MDT
14837         if [ $MDSCOUNT -gt 1 ]; then
14838                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14839                 verify_jobstats "$cmd" "mds2"
14840         fi
14841         # mknod
14842         cmd="mknod $DIR/$tfile c 1 3"
14843         verify_jobstats "$cmd" "$SINGLEMDS"
14844         # unlink
14845         cmd="rm -f $DIR/$tfile"
14846         verify_jobstats "$cmd" "$SINGLEMDS"
14847         # create all files on OST0000 so verify_jobstats can find OST stats
14848         # open & close
14849         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14850         verify_jobstats "$cmd" "$SINGLEMDS"
14851         # setattr
14852         cmd="touch $DIR/$tfile"
14853         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14854         # write
14855         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14856         verify_jobstats "$cmd" "ost1"
14857         # read
14858         cancel_lru_locks osc
14859         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14860         verify_jobstats "$cmd" "ost1"
14861         # truncate
14862         cmd="$TRUNCATE $DIR/$tfile 0"
14863         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14864         # rename
14865         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14866         verify_jobstats "$cmd" "$SINGLEMDS"
14867         # jobstats expiry - sleep until old stats should be expired
14868         local left=$((new_interval + 5 - (SECONDS - start)))
14869         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14870                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14871                         "0" $left
14872         cmd="mkdir $DIR/$tdir.expire"
14873         verify_jobstats "$cmd" "$SINGLEMDS"
14874         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14875             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14876
14877         # Ensure that jobid are present in changelog (if supported by MDS)
14878         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14879                 changelog_dump | tail -10
14880                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14881                 [ $jobids -eq 9 ] ||
14882                         error "Wrong changelog jobid count $jobids != 9"
14883
14884                 # LU-5862
14885                 JOBENV="disable"
14886                 jobstats_set $JOBENV
14887                 touch $DIR/$tfile
14888                 changelog_dump | grep $tfile
14889                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14890                 [ $jobids -eq 0 ] ||
14891                         error "Unexpected jobids when jobid_var=$JOBENV"
14892         fi
14893
14894         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14895         JOBENV="JOBCOMPLEX"
14896         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14897
14898         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14899 }
14900 run_test 205 "Verify job stats"
14901
14902 # LU-1480, LU-1773 and LU-1657
14903 test_206() {
14904         mkdir -p $DIR/$tdir
14905         $LFS setstripe -c -1 $DIR/$tdir
14906 #define OBD_FAIL_LOV_INIT 0x1403
14907         $LCTL set_param fail_loc=0xa0001403
14908         $LCTL set_param fail_val=1
14909         touch $DIR/$tdir/$tfile || true
14910 }
14911 run_test 206 "fail lov_init_raid0() doesn't lbug"
14912
14913 test_207a() {
14914         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14915         local fsz=`stat -c %s $DIR/$tfile`
14916         cancel_lru_locks mdc
14917
14918         # do not return layout in getattr intent
14919 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14920         $LCTL set_param fail_loc=0x170
14921         local sz=`stat -c %s $DIR/$tfile`
14922
14923         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14924
14925         rm -rf $DIR/$tfile
14926 }
14927 run_test 207a "can refresh layout at glimpse"
14928
14929 test_207b() {
14930         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14931         local cksum=`md5sum $DIR/$tfile`
14932         local fsz=`stat -c %s $DIR/$tfile`
14933         cancel_lru_locks mdc
14934         cancel_lru_locks osc
14935
14936         # do not return layout in getattr intent
14937 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14938         $LCTL set_param fail_loc=0x171
14939
14940         # it will refresh layout after the file is opened but before read issues
14941         echo checksum is "$cksum"
14942         echo "$cksum" |md5sum -c --quiet || error "file differs"
14943
14944         rm -rf $DIR/$tfile
14945 }
14946 run_test 207b "can refresh layout at open"
14947
14948 test_208() {
14949         # FIXME: in this test suite, only RD lease is used. This is okay
14950         # for now as only exclusive open is supported. After generic lease
14951         # is done, this test suite should be revised. - Jinshan
14952
14953         remote_mds_nodsh && skip "remote MDS with nodsh"
14954         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14955                 skip "Need MDS version at least 2.4.52"
14956
14957         echo "==== test 1: verify get lease work"
14958         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14959
14960         echo "==== test 2: verify lease can be broken by upcoming open"
14961         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14962         local PID=$!
14963         sleep 1
14964
14965         $MULTIOP $DIR/$tfile oO_RDONLY:c
14966         kill -USR1 $PID && wait $PID || error "break lease error"
14967
14968         echo "==== test 3: verify lease can't be granted if an open already exists"
14969         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14970         local PID=$!
14971         sleep 1
14972
14973         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14974         kill -USR1 $PID && wait $PID || error "open file error"
14975
14976         echo "==== test 4: lease can sustain over recovery"
14977         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14978         PID=$!
14979         sleep 1
14980
14981         fail mds1
14982
14983         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14984
14985         echo "==== test 5: lease broken can't be regained by replay"
14986         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14987         PID=$!
14988         sleep 1
14989
14990         # open file to break lease and then recovery
14991         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14992         fail mds1
14993
14994         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14995
14996         rm -f $DIR/$tfile
14997 }
14998 run_test 208 "Exclusive open"
14999
15000 test_209() {
15001         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15002                 skip_env "must have disp_stripe"
15003
15004         touch $DIR/$tfile
15005         sync; sleep 5; sync;
15006
15007         echo 3 > /proc/sys/vm/drop_caches
15008         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15009
15010         # open/close 500 times
15011         for i in $(seq 500); do
15012                 cat $DIR/$tfile
15013         done
15014
15015         echo 3 > /proc/sys/vm/drop_caches
15016         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15017
15018         echo "before: $req_before, after: $req_after"
15019         [ $((req_after - req_before)) -ge 300 ] &&
15020                 error "open/close requests are not freed"
15021         return 0
15022 }
15023 run_test 209 "read-only open/close requests should be freed promptly"
15024
15025 test_212() {
15026         size=`date +%s`
15027         size=$((size % 8192 + 1))
15028         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
15029         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
15030         rm -f $DIR/f212 $DIR/f212.xyz
15031 }
15032 run_test 212 "Sendfile test ============================================"
15033
15034 test_213() {
15035         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
15036         cancel_lru_locks osc
15037         lctl set_param fail_loc=0x8000040f
15038         # generate a read lock
15039         cat $DIR/$tfile > /dev/null
15040         # write to the file, it will try to cancel the above read lock.
15041         cat /etc/hosts >> $DIR/$tfile
15042 }
15043 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
15044
15045 test_214() { # for bug 20133
15046         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
15047         for (( i=0; i < 340; i++ )) ; do
15048                 touch $DIR/$tdir/d214c/a$i
15049         done
15050
15051         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
15052         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
15053         ls $DIR/d214c || error "ls $DIR/d214c failed"
15054         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
15055         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
15056 }
15057 run_test 214 "hash-indexed directory test - bug 20133"
15058
15059 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
15060 create_lnet_proc_files() {
15061         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
15062 }
15063
15064 # counterpart of create_lnet_proc_files
15065 remove_lnet_proc_files() {
15066         rm -f $TMP/lnet_$1.sys
15067 }
15068
15069 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15070 # 3rd arg as regexp for body
15071 check_lnet_proc_stats() {
15072         local l=$(cat "$TMP/lnet_$1" |wc -l)
15073         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
15074
15075         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
15076 }
15077
15078 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15079 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
15080 # optional and can be regexp for 2nd line (lnet.routes case)
15081 check_lnet_proc_entry() {
15082         local blp=2          # blp stands for 'position of 1st line of body'
15083         [ -z "$5" ] || blp=3 # lnet.routes case
15084
15085         local l=$(cat "$TMP/lnet_$1" |wc -l)
15086         # subtracting one from $blp because the body can be empty
15087         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
15088
15089         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
15090                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
15091
15092         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
15093                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
15094
15095         # bail out if any unexpected line happened
15096         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15097         [ "$?" != 0 ] || error "$2 misformatted"
15098 }
15099
15100 test_215() { # for bugs 18102, 21079, 21517
15101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15102
15103         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15104         local P='[1-9][0-9]*'           # positive numeric
15105         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15106         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15107         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15108         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15109
15110         local L1 # regexp for 1st line
15111         local L2 # regexp for 2nd line (optional)
15112         local BR # regexp for the rest (body)
15113
15114         # lnet.stats should look as 11 space-separated non-negative numerics
15115         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15116         create_lnet_proc_files "stats"
15117         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15118         remove_lnet_proc_files "stats"
15119
15120         # lnet.routes should look like this:
15121         # Routing disabled/enabled
15122         # net hops priority state router
15123         # where net is a string like tcp0, hops > 0, priority >= 0,
15124         # state is up/down,
15125         # router is a string like 192.168.1.1@tcp2
15126         L1="^Routing (disabled|enabled)$"
15127         L2="^net +hops +priority +state +router$"
15128         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15129         create_lnet_proc_files "routes"
15130         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15131         remove_lnet_proc_files "routes"
15132
15133         # lnet.routers should look like this:
15134         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15135         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15136         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15137         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15138         L1="^ref +rtr_ref +alive +router$"
15139         BR="^$P +$P +(up|down) +$NID$"
15140         create_lnet_proc_files "routers"
15141         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15142         remove_lnet_proc_files "routers"
15143
15144         # lnet.peers should look like this:
15145         # nid refs state last max rtr min tx min queue
15146         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15147         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15148         # numeric (0 or >0 or <0), queue >= 0.
15149         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15150         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15151         create_lnet_proc_files "peers"
15152         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15153         remove_lnet_proc_files "peers"
15154
15155         # lnet.buffers  should look like this:
15156         # pages count credits min
15157         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15158         L1="^pages +count +credits +min$"
15159         BR="^ +$N +$N +$I +$I$"
15160         create_lnet_proc_files "buffers"
15161         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15162         remove_lnet_proc_files "buffers"
15163
15164         # lnet.nis should look like this:
15165         # nid status alive refs peer rtr max tx min
15166         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15167         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15168         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15169         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15170         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15171         create_lnet_proc_files "nis"
15172         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15173         remove_lnet_proc_files "nis"
15174
15175         # can we successfully write to lnet.stats?
15176         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15177 }
15178 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15179
15180 test_216() { # bug 20317
15181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15182         remote_ost_nodsh && skip "remote OST with nodsh"
15183
15184         local node
15185         local facets=$(get_facets OST)
15186         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15187
15188         save_lustre_params client "osc.*.contention_seconds" > $p
15189         save_lustre_params $facets \
15190                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15191         save_lustre_params $facets \
15192                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15193         save_lustre_params $facets \
15194                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15195         clear_stats osc.*.osc_stats
15196
15197         # agressive lockless i/o settings
15198         do_nodes $(comma_list $(osts_nodes)) \
15199                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15200                         ldlm.namespaces.filter-*.contended_locks=0 \
15201                         ldlm.namespaces.filter-*.contention_seconds=60"
15202         lctl set_param -n osc.*.contention_seconds=60
15203
15204         $DIRECTIO write $DIR/$tfile 0 10 4096
15205         $CHECKSTAT -s 40960 $DIR/$tfile
15206
15207         # disable lockless i/o
15208         do_nodes $(comma_list $(osts_nodes)) \
15209                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15210                         ldlm.namespaces.filter-*.contended_locks=32 \
15211                         ldlm.namespaces.filter-*.contention_seconds=0"
15212         lctl set_param -n osc.*.contention_seconds=0
15213         clear_stats osc.*.osc_stats
15214
15215         dd if=/dev/zero of=$DIR/$tfile count=0
15216         $CHECKSTAT -s 0 $DIR/$tfile
15217
15218         restore_lustre_params <$p
15219         rm -f $p
15220         rm $DIR/$tfile
15221 }
15222 run_test 216 "check lockless direct write updates file size and kms correctly"
15223
15224 test_217() { # bug 22430
15225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15226
15227         local node
15228         local nid
15229
15230         for node in $(nodes_list); do
15231                 nid=$(host_nids_address $node $NETTYPE)
15232                 if [[ $nid = *-* ]] ; then
15233                         echo "lctl ping $(h2nettype $nid)"
15234                         lctl ping $(h2nettype $nid)
15235                 else
15236                         echo "skipping $node (no hyphen detected)"
15237                 fi
15238         done
15239 }
15240 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15241
15242 test_218() {
15243        # do directio so as not to populate the page cache
15244        log "creating a 10 Mb file"
15245        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15246        log "starting reads"
15247        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15248        log "truncating the file"
15249        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15250        log "killing dd"
15251        kill %+ || true # reads might have finished
15252        echo "wait until dd is finished"
15253        wait
15254        log "removing the temporary file"
15255        rm -rf $DIR/$tfile || error "tmp file removal failed"
15256 }
15257 run_test 218 "parallel read and truncate should not deadlock"
15258
15259 test_219() {
15260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15261
15262         # write one partial page
15263         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15264         # set no grant so vvp_io_commit_write will do sync write
15265         $LCTL set_param fail_loc=0x411
15266         # write a full page at the end of file
15267         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15268
15269         $LCTL set_param fail_loc=0
15270         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15271         $LCTL set_param fail_loc=0x411
15272         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15273
15274         # LU-4201
15275         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15276         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15277 }
15278 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15279
15280 test_220() { #LU-325
15281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15282         remote_ost_nodsh && skip "remote OST with nodsh"
15283         remote_mds_nodsh && skip "remote MDS with nodsh"
15284         remote_mgs_nodsh && skip "remote MGS with nodsh"
15285
15286         local OSTIDX=0
15287
15288         # create on MDT0000 so the last_id and next_id are correct
15289         mkdir $DIR/$tdir
15290         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15291         OST=${OST%_UUID}
15292
15293         # on the mdt's osc
15294         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15295         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15296                         osp.$mdtosc_proc1.prealloc_last_id)
15297         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15298                         osp.$mdtosc_proc1.prealloc_next_id)
15299
15300         $LFS df -i
15301
15302         if ! combined_mgs_mds ; then
15303                 mount_mgs_client
15304         fi
15305
15306         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15307         #define OBD_FAIL_OST_ENOINO              0x229
15308         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15309         create_pool $FSNAME.$TESTNAME || return 1
15310         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15311
15312         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15313
15314         MDSOBJS=$((last_id - next_id))
15315         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15316
15317         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15318         echo "OST still has $count kbytes free"
15319
15320         echo "create $MDSOBJS files @next_id..."
15321         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15322
15323         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15324                         osp.$mdtosc_proc1.prealloc_last_id)
15325         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15326                         osp.$mdtosc_proc1.prealloc_next_id)
15327
15328         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15329         $LFS df -i
15330
15331         echo "cleanup..."
15332
15333         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15334         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15335
15336         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15337                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15338         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15339                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15340         echo "unlink $MDSOBJS files @$next_id..."
15341         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15342
15343         if ! combined_mgs_mds ; then
15344                 umount_mgs_client
15345         fi
15346 }
15347 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15348
15349 test_221() {
15350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15351
15352         dd if=`which date` of=$MOUNT/date oflag=sync
15353         chmod +x $MOUNT/date
15354
15355         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15356         $LCTL set_param fail_loc=0x80001401
15357
15358         $MOUNT/date > /dev/null
15359         rm -f $MOUNT/date
15360 }
15361 run_test 221 "make sure fault and truncate race to not cause OOM"
15362
15363 test_222a () {
15364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15365
15366         rm -rf $DIR/$tdir
15367         test_mkdir $DIR/$tdir
15368         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15369         createmany -o $DIR/$tdir/$tfile 10
15370         cancel_lru_locks mdc
15371         cancel_lru_locks osc
15372         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15373         $LCTL set_param fail_loc=0x31a
15374         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15375         $LCTL set_param fail_loc=0
15376         rm -r $DIR/$tdir
15377 }
15378 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15379
15380 test_222b () {
15381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15382
15383         rm -rf $DIR/$tdir
15384         test_mkdir $DIR/$tdir
15385         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15386         createmany -o $DIR/$tdir/$tfile 10
15387         cancel_lru_locks mdc
15388         cancel_lru_locks osc
15389         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15390         $LCTL set_param fail_loc=0x31a
15391         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15392         $LCTL set_param fail_loc=0
15393 }
15394 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15395
15396 test_223 () {
15397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15398
15399         rm -rf $DIR/$tdir
15400         test_mkdir $DIR/$tdir
15401         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15402         createmany -o $DIR/$tdir/$tfile 10
15403         cancel_lru_locks mdc
15404         cancel_lru_locks osc
15405         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15406         $LCTL set_param fail_loc=0x31b
15407         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15408         $LCTL set_param fail_loc=0
15409         rm -r $DIR/$tdir
15410 }
15411 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15412
15413 test_224a() { # LU-1039, MRP-303
15414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15415
15416         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15417         $LCTL set_param fail_loc=0x508
15418         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15419         $LCTL set_param fail_loc=0
15420         df $DIR
15421 }
15422 run_test 224a "Don't panic on bulk IO failure"
15423
15424 test_224b() { # LU-1039, MRP-303
15425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15426
15427         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
15428         cancel_lru_locks osc
15429         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
15430         $LCTL set_param fail_loc=0x515
15431         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
15432         $LCTL set_param fail_loc=0
15433         df $DIR
15434 }
15435 run_test 224b "Don't panic on bulk IO failure"
15436
15437 test_224c() { # LU-6441
15438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15439         remote_mds_nodsh && skip "remote MDS with nodsh"
15440
15441         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15442         save_writethrough $p
15443         set_cache writethrough on
15444
15445         local pages_per_rpc=$($LCTL get_param \
15446                                 osc.*.max_pages_per_rpc)
15447         local at_max=$($LCTL get_param -n at_max)
15448         local timeout=$($LCTL get_param -n timeout)
15449         local test_at="at_max"
15450         local param_at="$FSNAME.sys.at_max"
15451         local test_timeout="timeout"
15452         local param_timeout="$FSNAME.sys.timeout"
15453
15454         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
15455
15456         set_persistent_param_and_check client "$test_at" "$param_at" 0
15457         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
15458
15459         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
15460         do_facet ost1 "$LCTL set_param fail_loc=0x520"
15461         $LFS setstripe -c 1 -i 0 $DIR/$tfile
15462         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
15463         sync
15464         do_facet ost1 "$LCTL set_param fail_loc=0"
15465
15466         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
15467         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
15468                 $timeout
15469
15470         $LCTL set_param -n $pages_per_rpc
15471         restore_lustre_params < $p
15472         rm -f $p
15473 }
15474 run_test 224c "Don't hang if one of md lost during large bulk RPC"
15475
15476 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
15477 test_225a () {
15478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15479         if [ -z ${MDSSURVEY} ]; then
15480                 skip_env "mds-survey not found"
15481         fi
15482         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15483                 skip "Need MDS version at least 2.2.51"
15484
15485         local mds=$(facet_host $SINGLEMDS)
15486         local target=$(do_nodes $mds 'lctl dl' |
15487                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15488
15489         local cmd1="file_count=1000 thrhi=4"
15490         local cmd2="dir_count=2 layer=mdd stripe_count=0"
15491         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15492         local cmd="$cmd1 $cmd2 $cmd3"
15493
15494         rm -f ${TMP}/mds_survey*
15495         echo + $cmd
15496         eval $cmd || error "mds-survey with zero-stripe failed"
15497         cat ${TMP}/mds_survey*
15498         rm -f ${TMP}/mds_survey*
15499 }
15500 run_test 225a "Metadata survey sanity with zero-stripe"
15501
15502 test_225b () {
15503         if [ -z ${MDSSURVEY} ]; then
15504                 skip_env "mds-survey not found"
15505         fi
15506         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15507                 skip "Need MDS version at least 2.2.51"
15508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15509         remote_mds_nodsh && skip "remote MDS with nodsh"
15510         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
15511                 skip_env "Need to mount OST to test"
15512         fi
15513
15514         local mds=$(facet_host $SINGLEMDS)
15515         local target=$(do_nodes $mds 'lctl dl' |
15516                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15517
15518         local cmd1="file_count=1000 thrhi=4"
15519         local cmd2="dir_count=2 layer=mdd stripe_count=1"
15520         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15521         local cmd="$cmd1 $cmd2 $cmd3"
15522
15523         rm -f ${TMP}/mds_survey*
15524         echo + $cmd
15525         eval $cmd || error "mds-survey with stripe_count failed"
15526         cat ${TMP}/mds_survey*
15527         rm -f ${TMP}/mds_survey*
15528 }
15529 run_test 225b "Metadata survey sanity with stripe_count = 1"
15530
15531 mcreate_path2fid () {
15532         local mode=$1
15533         local major=$2
15534         local minor=$3
15535         local name=$4
15536         local desc=$5
15537         local path=$DIR/$tdir/$name
15538         local fid
15539         local rc
15540         local fid_path
15541
15542         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
15543                 error "cannot create $desc"
15544
15545         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
15546         rc=$?
15547         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
15548
15549         fid_path=$($LFS fid2path $MOUNT $fid)
15550         rc=$?
15551         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
15552
15553         [ "$path" == "$fid_path" ] ||
15554                 error "fid2path returned $fid_path, expected $path"
15555
15556         echo "pass with $path and $fid"
15557 }
15558
15559 test_226a () {
15560         rm -rf $DIR/$tdir
15561         mkdir -p $DIR/$tdir
15562
15563         mcreate_path2fid 0010666 0 0 fifo "FIFO"
15564         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15565         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15566         mcreate_path2fid 0040666 0 0 dir "directory"
15567         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15568         mcreate_path2fid 0100666 0 0 file "regular file"
15569         mcreate_path2fid 0120666 0 0 link "symbolic link"
15570         mcreate_path2fid 0140666 0 0 sock "socket"
15571 }
15572 run_test 226a "call path2fid and fid2path on files of all type"
15573
15574 test_226b () {
15575         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15576
15577         local MDTIDX=1
15578
15579         rm -rf $DIR/$tdir
15580         mkdir -p $DIR/$tdir
15581         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15582                 error "create remote directory failed"
15583         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15584         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15585                                 "character special file (null)"
15586         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15587                                 "character special file (no device)"
15588         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15589         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15590                                 "block special file (loop)"
15591         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15592         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15593         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15594 }
15595 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15596
15597 # LU-1299 Executing or running ldd on a truncated executable does not
15598 # cause an out-of-memory condition.
15599 test_227() {
15600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15601         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15602
15603         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15604         chmod +x $MOUNT/date
15605
15606         $MOUNT/date > /dev/null
15607         ldd $MOUNT/date > /dev/null
15608         rm -f $MOUNT/date
15609 }
15610 run_test 227 "running truncated executable does not cause OOM"
15611
15612 # LU-1512 try to reuse idle OI blocks
15613 test_228a() {
15614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15615         remote_mds_nodsh && skip "remote MDS with nodsh"
15616         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15617
15618         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15619         local myDIR=$DIR/$tdir
15620
15621         mkdir -p $myDIR
15622         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15623         $LCTL set_param fail_loc=0x80001002
15624         createmany -o $myDIR/t- 10000
15625         $LCTL set_param fail_loc=0
15626         # The guard is current the largest FID holder
15627         touch $myDIR/guard
15628         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15629                     tr -d '[')
15630         local IDX=$(($SEQ % 64))
15631
15632         do_facet $SINGLEMDS sync
15633         # Make sure journal flushed.
15634         sleep 6
15635         local blk1=$(do_facet $SINGLEMDS \
15636                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15637                      grep Blockcount | awk '{print $4}')
15638
15639         # Remove old files, some OI blocks will become idle.
15640         unlinkmany $myDIR/t- 10000
15641         # Create new files, idle OI blocks should be reused.
15642         createmany -o $myDIR/t- 2000
15643         do_facet $SINGLEMDS sync
15644         # Make sure journal flushed.
15645         sleep 6
15646         local blk2=$(do_facet $SINGLEMDS \
15647                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15648                      grep Blockcount | awk '{print $4}')
15649
15650         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15651 }
15652 run_test 228a "try to reuse idle OI blocks"
15653
15654 test_228b() {
15655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15656         remote_mds_nodsh && skip "remote MDS with nodsh"
15657         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15658
15659         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15660         local myDIR=$DIR/$tdir
15661
15662         mkdir -p $myDIR
15663         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15664         $LCTL set_param fail_loc=0x80001002
15665         createmany -o $myDIR/t- 10000
15666         $LCTL set_param fail_loc=0
15667         # The guard is current the largest FID holder
15668         touch $myDIR/guard
15669         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15670                     tr -d '[')
15671         local IDX=$(($SEQ % 64))
15672
15673         do_facet $SINGLEMDS sync
15674         # Make sure journal flushed.
15675         sleep 6
15676         local blk1=$(do_facet $SINGLEMDS \
15677                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15678                      grep Blockcount | awk '{print $4}')
15679
15680         # Remove old files, some OI blocks will become idle.
15681         unlinkmany $myDIR/t- 10000
15682
15683         # stop the MDT
15684         stop $SINGLEMDS || error "Fail to stop MDT."
15685         # remount the MDT
15686         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15687
15688         df $MOUNT || error "Fail to df."
15689         # Create new files, idle OI blocks should be reused.
15690         createmany -o $myDIR/t- 2000
15691         do_facet $SINGLEMDS sync
15692         # Make sure journal flushed.
15693         sleep 6
15694         local blk2=$(do_facet $SINGLEMDS \
15695                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15696                      grep Blockcount | awk '{print $4}')
15697
15698         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15699 }
15700 run_test 228b "idle OI blocks can be reused after MDT restart"
15701
15702 #LU-1881
15703 test_228c() {
15704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15705         remote_mds_nodsh && skip "remote MDS with nodsh"
15706         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15707
15708         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15709         local myDIR=$DIR/$tdir
15710
15711         mkdir -p $myDIR
15712         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15713         $LCTL set_param fail_loc=0x80001002
15714         # 20000 files can guarantee there are index nodes in the OI file
15715         createmany -o $myDIR/t- 20000
15716         $LCTL set_param fail_loc=0
15717         # The guard is current the largest FID holder
15718         touch $myDIR/guard
15719         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15720                     tr -d '[')
15721         local IDX=$(($SEQ % 64))
15722
15723         do_facet $SINGLEMDS sync
15724         # Make sure journal flushed.
15725         sleep 6
15726         local blk1=$(do_facet $SINGLEMDS \
15727                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15728                      grep Blockcount | awk '{print $4}')
15729
15730         # Remove old files, some OI blocks will become idle.
15731         unlinkmany $myDIR/t- 20000
15732         rm -f $myDIR/guard
15733         # The OI file should become empty now
15734
15735         # Create new files, idle OI blocks should be reused.
15736         createmany -o $myDIR/t- 2000
15737         do_facet $SINGLEMDS sync
15738         # Make sure journal flushed.
15739         sleep 6
15740         local blk2=$(do_facet $SINGLEMDS \
15741                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15742                      grep Blockcount | awk '{print $4}')
15743
15744         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15745 }
15746 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15747
15748 test_229() { # LU-2482, LU-3448
15749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15750         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15751         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15752                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15753
15754         rm -f $DIR/$tfile
15755
15756         # Create a file with a released layout and stripe count 2.
15757         $MULTIOP $DIR/$tfile H2c ||
15758                 error "failed to create file with released layout"
15759
15760         $LFS getstripe -v $DIR/$tfile
15761
15762         local pattern=$($LFS getstripe -L $DIR/$tfile)
15763         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15764
15765         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15766                 error "getstripe"
15767         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15768         stat $DIR/$tfile || error "failed to stat released file"
15769
15770         chown $RUNAS_ID $DIR/$tfile ||
15771                 error "chown $RUNAS_ID $DIR/$tfile failed"
15772
15773         chgrp $RUNAS_ID $DIR/$tfile ||
15774                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15775
15776         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15777         rm $DIR/$tfile || error "failed to remove released file"
15778 }
15779 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15780
15781 test_230a() {
15782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15783         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15784         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15785                 skip "Need MDS version at least 2.11.52"
15786
15787         local MDTIDX=1
15788
15789         test_mkdir $DIR/$tdir
15790         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15791         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15792         [ $mdt_idx -ne 0 ] &&
15793                 error "create local directory on wrong MDT $mdt_idx"
15794
15795         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15796                         error "create remote directory failed"
15797         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15798         [ $mdt_idx -ne $MDTIDX ] &&
15799                 error "create remote directory on wrong MDT $mdt_idx"
15800
15801         createmany -o $DIR/$tdir/test_230/t- 10 ||
15802                 error "create files on remote directory failed"
15803         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15804         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15805         rm -r $DIR/$tdir || error "unlink remote directory failed"
15806 }
15807 run_test 230a "Create remote directory and files under the remote directory"
15808
15809 test_230b() {
15810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15811         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15812         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15813                 skip "Need MDS version at least 2.11.52"
15814
15815         local MDTIDX=1
15816         local mdt_index
15817         local i
15818         local file
15819         local pid
15820         local stripe_count
15821         local migrate_dir=$DIR/$tdir/migrate_dir
15822         local other_dir=$DIR/$tdir/other_dir
15823
15824         test_mkdir $DIR/$tdir
15825         test_mkdir -i0 -c1 $migrate_dir
15826         test_mkdir -i0 -c1 $other_dir
15827         for ((i=0; i<10; i++)); do
15828                 mkdir -p $migrate_dir/dir_${i}
15829                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15830                         error "create files under remote dir failed $i"
15831         done
15832
15833         cp /etc/passwd $migrate_dir/$tfile
15834         cp /etc/passwd $other_dir/$tfile
15835         chattr +SAD $migrate_dir
15836         chattr +SAD $migrate_dir/$tfile
15837
15838         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15839         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15840         local old_dir_mode=$(stat -c%f $migrate_dir)
15841         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15842
15843         mkdir -p $migrate_dir/dir_default_stripe2
15844         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15845         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15846
15847         mkdir -p $other_dir
15848         ln $migrate_dir/$tfile $other_dir/luna
15849         ln $migrate_dir/$tfile $migrate_dir/sofia
15850         ln $other_dir/$tfile $migrate_dir/david
15851         ln -s $migrate_dir/$tfile $other_dir/zachary
15852         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15853         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15854
15855         $LFS migrate -m $MDTIDX $migrate_dir ||
15856                 error "fails on migrating remote dir to MDT1"
15857
15858         echo "migratate to MDT1, then checking.."
15859         for ((i = 0; i < 10; i++)); do
15860                 for file in $(find $migrate_dir/dir_${i}); do
15861                         mdt_index=$($LFS getstripe -m $file)
15862                         [ $mdt_index == $MDTIDX ] ||
15863                                 error "$file is not on MDT${MDTIDX}"
15864                 done
15865         done
15866
15867         # the multiple link file should still in MDT0
15868         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15869         [ $mdt_index == 0 ] ||
15870                 error "$file is not on MDT${MDTIDX}"
15871
15872         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15873         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15874                 error " expect $old_dir_flag get $new_dir_flag"
15875
15876         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15877         [ "$old_file_flag" = "$new_file_flag" ] ||
15878                 error " expect $old_file_flag get $new_file_flag"
15879
15880         local new_dir_mode=$(stat -c%f $migrate_dir)
15881         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15882                 error "expect mode $old_dir_mode get $new_dir_mode"
15883
15884         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15885         [ "$old_file_mode" = "$new_file_mode" ] ||
15886                 error "expect mode $old_file_mode get $new_file_mode"
15887
15888         diff /etc/passwd $migrate_dir/$tfile ||
15889                 error "$tfile different after migration"
15890
15891         diff /etc/passwd $other_dir/luna ||
15892                 error "luna different after migration"
15893
15894         diff /etc/passwd $migrate_dir/sofia ||
15895                 error "sofia different after migration"
15896
15897         diff /etc/passwd $migrate_dir/david ||
15898                 error "david different after migration"
15899
15900         diff /etc/passwd $other_dir/zachary ||
15901                 error "zachary different after migration"
15902
15903         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15904                 error "${tfile}_ln different after migration"
15905
15906         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15907                 error "${tfile}_ln_other different after migration"
15908
15909         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15910         [ $stripe_count = 2 ] ||
15911                 error "dir strpe_count $d != 2 after migration."
15912
15913         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15914         [ $stripe_count = 2 ] ||
15915                 error "file strpe_count $d != 2 after migration."
15916
15917         #migrate back to MDT0
15918         MDTIDX=0
15919
15920         $LFS migrate -m $MDTIDX $migrate_dir ||
15921                 error "fails on migrating remote dir to MDT0"
15922
15923         echo "migrate back to MDT0, checking.."
15924         for file in $(find $migrate_dir); do
15925                 mdt_index=$($LFS getstripe -m $file)
15926                 [ $mdt_index == $MDTIDX ] ||
15927                         error "$file is not on MDT${MDTIDX}"
15928         done
15929
15930         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15931         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15932                 error " expect $old_dir_flag get $new_dir_flag"
15933
15934         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15935         [ "$old_file_flag" = "$new_file_flag" ] ||
15936                 error " expect $old_file_flag get $new_file_flag"
15937
15938         local new_dir_mode=$(stat -c%f $migrate_dir)
15939         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15940                 error "expect mode $old_dir_mode get $new_dir_mode"
15941
15942         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15943         [ "$old_file_mode" = "$new_file_mode" ] ||
15944                 error "expect mode $old_file_mode get $new_file_mode"
15945
15946         diff /etc/passwd ${migrate_dir}/$tfile ||
15947                 error "$tfile different after migration"
15948
15949         diff /etc/passwd ${other_dir}/luna ||
15950                 error "luna different after migration"
15951
15952         diff /etc/passwd ${migrate_dir}/sofia ||
15953                 error "sofia different after migration"
15954
15955         diff /etc/passwd ${other_dir}/zachary ||
15956                 error "zachary different after migration"
15957
15958         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15959                 error "${tfile}_ln different after migration"
15960
15961         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15962                 error "${tfile}_ln_other different after migration"
15963
15964         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15965         [ $stripe_count = 2 ] ||
15966                 error "dir strpe_count $d != 2 after migration."
15967
15968         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15969         [ $stripe_count = 2 ] ||
15970                 error "file strpe_count $d != 2 after migration."
15971
15972         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15973 }
15974 run_test 230b "migrate directory"
15975
15976 test_230c() {
15977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15978         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15979         remote_mds_nodsh && skip "remote MDS with nodsh"
15980         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15981                 skip "Need MDS version at least 2.11.52"
15982
15983         local MDTIDX=1
15984         local total=3
15985         local mdt_index
15986         local file
15987         local migrate_dir=$DIR/$tdir/migrate_dir
15988
15989         #If migrating directory fails in the middle, all entries of
15990         #the directory is still accessiable.
15991         test_mkdir $DIR/$tdir
15992         test_mkdir -i0 -c1 $migrate_dir
15993         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15994         stat $migrate_dir
15995         createmany -o $migrate_dir/f $total ||
15996                 error "create files under ${migrate_dir} failed"
15997
15998         # fail after migrating top dir, and this will fail only once, so the
15999         # first sub file migration will fail (currently f3), others succeed.
16000         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16001         do_facet mds1 lctl set_param fail_loc=0x1801
16002         local t=$(ls $migrate_dir | wc -l)
16003         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
16004                 error "migrate should fail"
16005         local u=$(ls $migrate_dir | wc -l)
16006         [ "$u" == "$t" ] || error "$u != $t during migration"
16007
16008         # add new dir/file should succeed
16009         mkdir $migrate_dir/dir ||
16010                 error "mkdir failed under migrating directory"
16011         touch $migrate_dir/file ||
16012                 error "create file failed under migrating directory"
16013
16014         # add file with existing name should fail
16015         for file in $migrate_dir/f*; do
16016                 stat $file > /dev/null || error "stat $file failed"
16017                 $OPENFILE -f O_CREAT:O_EXCL $file &&
16018                         error "open(O_CREAT|O_EXCL) $file should fail"
16019                 $MULTIOP $file m && error "create $file should fail"
16020                 touch $DIR/$tdir/remote_dir/$tfile ||
16021                         error "touch $tfile failed"
16022                 ln $DIR/$tdir/remote_dir/$tfile $file &&
16023                         error "link $file should fail"
16024                 mdt_index=$($LFS getstripe -m $file)
16025                 if [ $mdt_index == 0 ]; then
16026                         # file failed to migrate is not allowed to rename to
16027                         mv $DIR/$tdir/remote_dir/$tfile $file &&
16028                                 error "rename to $file should fail"
16029                 else
16030                         mv $DIR/$tdir/remote_dir/$tfile $file ||
16031                                 error "rename to $file failed"
16032                 fi
16033                 echo hello >> $file || error "write $file failed"
16034         done
16035
16036         # resume migration with different options should fail
16037         $LFS migrate -m 0 $migrate_dir &&
16038                 error "migrate -m 0 $migrate_dir should fail"
16039
16040         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
16041                 error "migrate -c 2 $migrate_dir should fail"
16042
16043         # resume migration should succeed
16044         $LFS migrate -m $MDTIDX $migrate_dir ||
16045                 error "migrate $migrate_dir failed"
16046
16047         echo "Finish migration, then checking.."
16048         for file in $(find $migrate_dir); do
16049                 mdt_index=$($LFS getstripe -m $file)
16050                 [ $mdt_index == $MDTIDX ] ||
16051                         error "$file is not on MDT${MDTIDX}"
16052         done
16053
16054         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16055 }
16056 run_test 230c "check directory accessiblity if migration failed"
16057
16058 test_230d() {
16059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16060         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16061         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16062                 skip "Need MDS version at least 2.11.52"
16063         # LU-11235
16064         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
16065
16066         local migrate_dir=$DIR/$tdir/migrate_dir
16067         local old_index
16068         local new_index
16069         local old_count
16070         local new_count
16071         local new_hash
16072         local mdt_index
16073         local i
16074         local j
16075
16076         old_index=$((RANDOM % MDSCOUNT))
16077         old_count=$((MDSCOUNT - old_index))
16078         new_index=$((RANDOM % MDSCOUNT))
16079         new_count=$((MDSCOUNT - new_index))
16080         new_hash="all_char"
16081
16082         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
16083         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
16084
16085         test_mkdir $DIR/$tdir
16086         test_mkdir -i $old_index -c $old_count $migrate_dir
16087
16088         for ((i=0; i<100; i++)); do
16089                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
16090                 createmany -o $migrate_dir/dir_${i}/f 100 ||
16091                         error "create files under remote dir failed $i"
16092         done
16093
16094         echo -n "Migrate from MDT$old_index "
16095         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
16096         echo -n "to MDT$new_index"
16097         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16098         echo
16099
16100         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16101         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16102                 error "migrate remote dir error"
16103
16104         echo "Finish migration, then checking.."
16105         for file in $(find $migrate_dir); do
16106                 mdt_index=$($LFS getstripe -m $file)
16107                 if [ $mdt_index -lt $new_index ] ||
16108                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16109                         error "$file is on MDT$mdt_index"
16110                 fi
16111         done
16112
16113         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16114 }
16115 run_test 230d "check migrate big directory"
16116
16117 test_230e() {
16118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16119         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16120         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16121                 skip "Need MDS version at least 2.11.52"
16122
16123         local i
16124         local j
16125         local a_fid
16126         local b_fid
16127
16128         mkdir -p $DIR/$tdir
16129         mkdir $DIR/$tdir/migrate_dir
16130         mkdir $DIR/$tdir/other_dir
16131         touch $DIR/$tdir/migrate_dir/a
16132         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16133         ls $DIR/$tdir/other_dir
16134
16135         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16136                 error "migrate dir fails"
16137
16138         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16139         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16140
16141         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16142         [ $mdt_index == 0 ] || error "a is not on MDT0"
16143
16144         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16145                 error "migrate dir fails"
16146
16147         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16148         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16149
16150         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16151         [ $mdt_index == 1 ] || error "a is not on MDT1"
16152
16153         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16154         [ $mdt_index == 1 ] || error "b is not on MDT1"
16155
16156         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16157         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16158
16159         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16160
16161         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16162 }
16163 run_test 230e "migrate mulitple local link files"
16164
16165 test_230f() {
16166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16167         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16168         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16169                 skip "Need MDS version at least 2.11.52"
16170
16171         local a_fid
16172         local ln_fid
16173
16174         mkdir -p $DIR/$tdir
16175         mkdir $DIR/$tdir/migrate_dir
16176         $LFS mkdir -i1 $DIR/$tdir/other_dir
16177         touch $DIR/$tdir/migrate_dir/a
16178         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16179         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16180         ls $DIR/$tdir/other_dir
16181
16182         # a should be migrated to MDT1, since no other links on MDT0
16183         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16184                 error "#1 migrate dir fails"
16185         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16186         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16187         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16188         [ $mdt_index == 1 ] || error "a is not on MDT1"
16189
16190         # a should stay on MDT1, because it is a mulitple link file
16191         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16192                 error "#2 migrate dir fails"
16193         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16194         [ $mdt_index == 1 ] || error "a is not on MDT1"
16195
16196         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16197                 error "#3 migrate dir fails"
16198
16199         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16200         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16201         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16202
16203         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16204         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16205
16206         # a should be migrated to MDT0, since no other links on MDT1
16207         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16208                 error "#4 migrate dir fails"
16209         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16210         [ $mdt_index == 0 ] || error "a is not on MDT0"
16211
16212         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16213 }
16214 run_test 230f "migrate mulitple remote link files"
16215
16216 test_230g() {
16217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16218         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16219         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16220                 skip "Need MDS version at least 2.11.52"
16221
16222         mkdir -p $DIR/$tdir/migrate_dir
16223
16224         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16225                 error "migrating dir to non-exist MDT succeeds"
16226         true
16227 }
16228 run_test 230g "migrate dir to non-exist MDT"
16229
16230 test_230h() {
16231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16232         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16233         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16234                 skip "Need MDS version at least 2.11.52"
16235
16236         local mdt_index
16237
16238         mkdir -p $DIR/$tdir/migrate_dir
16239
16240         $LFS migrate -m1 $DIR &&
16241                 error "migrating mountpoint1 should fail"
16242
16243         $LFS migrate -m1 $DIR/$tdir/.. &&
16244                 error "migrating mountpoint2 should fail"
16245
16246         # same as mv
16247         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16248                 error "migrating $tdir/migrate_dir/.. should fail"
16249
16250         true
16251 }
16252 run_test 230h "migrate .. and root"
16253
16254 test_230i() {
16255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16256         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16257         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16258                 skip "Need MDS version at least 2.11.52"
16259
16260         mkdir -p $DIR/$tdir/migrate_dir
16261
16262         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16263                 error "migration fails with a tailing slash"
16264
16265         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16266                 error "migration fails with two tailing slashes"
16267 }
16268 run_test 230i "lfs migrate -m tolerates trailing slashes"
16269
16270 test_230j() {
16271         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16272         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16273                 skip "Need MDS version at least 2.11.52"
16274
16275         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16276         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16277                 error "create $tfile failed"
16278         cat /etc/passwd > $DIR/$tdir/$tfile
16279
16280         $LFS migrate -m 1 $DIR/$tdir
16281
16282         cmp /etc/passwd $DIR/$tdir/$tfile ||
16283                 error "DoM file mismatch after migration"
16284 }
16285 run_test 230j "DoM file data not changed after dir migration"
16286
16287 test_230k() {
16288         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16289         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16290                 skip "Need MDS version at least 2.11.56"
16291
16292         local total=20
16293         local files_on_starting_mdt=0
16294
16295         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16296         $LFS getdirstripe $DIR/$tdir
16297         for i in $(seq $total); do
16298                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16299                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16300                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16301         done
16302
16303         echo "$files_on_starting_mdt files on MDT0"
16304
16305         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16306         $LFS getdirstripe $DIR/$tdir
16307
16308         files_on_starting_mdt=0
16309         for i in $(seq $total); do
16310                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16311                         error "file $tfile.$i mismatch after migration"
16312                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16313                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16314         done
16315
16316         echo "$files_on_starting_mdt files on MDT1 after migration"
16317         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16318
16319         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16320         $LFS getdirstripe $DIR/$tdir
16321
16322         files_on_starting_mdt=0
16323         for i in $(seq $total); do
16324                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16325                         error "file $tfile.$i mismatch after 2nd migration"
16326                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16327                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16328         done
16329
16330         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16331         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16332
16333         true
16334 }
16335 run_test 230k "file data not changed after dir migration"
16336
16337 test_230l() {
16338         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16339         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16340                 skip "Need MDS version at least 2.11.56"
16341
16342         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16343         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16344                 error "create files under remote dir failed $i"
16345         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16346 }
16347 run_test 230l "readdir between MDTs won't crash"
16348
16349 test_231a()
16350 {
16351         # For simplicity this test assumes that max_pages_per_rpc
16352         # is the same across all OSCs
16353         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16354         local bulk_size=$((max_pages * PAGE_SIZE))
16355         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16356                                        head -n 1)
16357
16358         mkdir -p $DIR/$tdir
16359         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16360                 error "failed to set stripe with -S ${brw_size}M option"
16361
16362         # clear the OSC stats
16363         $LCTL set_param osc.*.stats=0 &>/dev/null
16364         stop_writeback
16365
16366         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
16367         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
16368                 oflag=direct &>/dev/null || error "dd failed"
16369
16370         sync; sleep 1; sync # just to be safe
16371         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
16372         if [ x$nrpcs != "x1" ]; then
16373                 $LCTL get_param osc.*.stats
16374                 error "found $nrpcs ost_write RPCs, not 1 as expected"
16375         fi
16376
16377         start_writeback
16378         # Drop the OSC cache, otherwise we will read from it
16379         cancel_lru_locks osc
16380
16381         # clear the OSC stats
16382         $LCTL set_param osc.*.stats=0 &>/dev/null
16383
16384         # Client reads $bulk_size.
16385         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
16386                 iflag=direct &>/dev/null || error "dd failed"
16387
16388         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
16389         if [ x$nrpcs != "x1" ]; then
16390                 $LCTL get_param osc.*.stats
16391                 error "found $nrpcs ost_read RPCs, not 1 as expected"
16392         fi
16393 }
16394 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
16395
16396 test_231b() {
16397         mkdir -p $DIR/$tdir
16398         local i
16399         for i in {0..1023}; do
16400                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
16401                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
16402                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
16403         done
16404         sync
16405 }
16406 run_test 231b "must not assert on fully utilized OST request buffer"
16407
16408 test_232a() {
16409         mkdir -p $DIR/$tdir
16410         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16411
16412         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16413         do_facet ost1 $LCTL set_param fail_loc=0x31c
16414
16415         # ignore dd failure
16416         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
16417
16418         do_facet ost1 $LCTL set_param fail_loc=0
16419         umount_client $MOUNT || error "umount failed"
16420         mount_client $MOUNT || error "mount failed"
16421         stop ost1 || error "cannot stop ost1"
16422         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16423 }
16424 run_test 232a "failed lock should not block umount"
16425
16426 test_232b() {
16427         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
16428                 skip "Need MDS version at least 2.10.58"
16429
16430         mkdir -p $DIR/$tdir
16431         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16432         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
16433         sync
16434         cancel_lru_locks osc
16435
16436         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16437         do_facet ost1 $LCTL set_param fail_loc=0x31c
16438
16439         # ignore failure
16440         $LFS data_version $DIR/$tdir/$tfile || true
16441
16442         do_facet ost1 $LCTL set_param fail_loc=0
16443         umount_client $MOUNT || error "umount failed"
16444         mount_client $MOUNT || error "mount failed"
16445         stop ost1 || error "cannot stop ost1"
16446         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16447 }
16448 run_test 232b "failed data version lock should not block umount"
16449
16450 test_233a() {
16451         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
16452                 skip "Need MDS version at least 2.3.64"
16453         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16454
16455         local fid=$($LFS path2fid $MOUNT)
16456
16457         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16458                 error "cannot access $MOUNT using its FID '$fid'"
16459 }
16460 run_test 233a "checking that OBF of the FS root succeeds"
16461
16462 test_233b() {
16463         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
16464                 skip "Need MDS version at least 2.5.90"
16465         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16466
16467         local fid=$($LFS path2fid $MOUNT/.lustre)
16468
16469         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16470                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
16471
16472         fid=$($LFS path2fid $MOUNT/.lustre/fid)
16473         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16474                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
16475 }
16476 run_test 233b "checking that OBF of the FS .lustre succeeds"
16477
16478 test_234() {
16479         local p="$TMP/sanityN-$TESTNAME.parameters"
16480         save_lustre_params client "llite.*.xattr_cache" > $p
16481         lctl set_param llite.*.xattr_cache 1 ||
16482                 skip_env "xattr cache is not supported"
16483
16484         mkdir -p $DIR/$tdir || error "mkdir failed"
16485         touch $DIR/$tdir/$tfile || error "touch failed"
16486         # OBD_FAIL_LLITE_XATTR_ENOMEM
16487         $LCTL set_param fail_loc=0x1405
16488         getfattr -n user.attr $DIR/$tdir/$tfile &&
16489                 error "getfattr should have failed with ENOMEM"
16490         $LCTL set_param fail_loc=0x0
16491         rm -rf $DIR/$tdir
16492
16493         restore_lustre_params < $p
16494         rm -f $p
16495 }
16496 run_test 234 "xattr cache should not crash on ENOMEM"
16497
16498 test_235() {
16499         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
16500                 skip "Need MDS version at least 2.4.52"
16501
16502         flock_deadlock $DIR/$tfile
16503         local RC=$?
16504         case $RC in
16505                 0)
16506                 ;;
16507                 124) error "process hangs on a deadlock"
16508                 ;;
16509                 *) error "error executing flock_deadlock $DIR/$tfile"
16510                 ;;
16511         esac
16512 }
16513 run_test 235 "LU-1715: flock deadlock detection does not work properly"
16514
16515 #LU-2935
16516 test_236() {
16517         check_swap_layouts_support
16518
16519         local ref1=/etc/passwd
16520         local ref2=/etc/group
16521         local file1=$DIR/$tdir/f1
16522         local file2=$DIR/$tdir/f2
16523
16524         test_mkdir -c1 $DIR/$tdir
16525         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
16526         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
16527         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
16528         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
16529         local fd=$(free_fd)
16530         local cmd="exec $fd<>$file2"
16531         eval $cmd
16532         rm $file2
16533         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
16534                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
16535         cmd="exec $fd>&-"
16536         eval $cmd
16537         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16538
16539         #cleanup
16540         rm -rf $DIR/$tdir
16541 }
16542 run_test 236 "Layout swap on open unlinked file"
16543
16544 # LU-4659 linkea consistency
16545 test_238() {
16546         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16547                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16548                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16549                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16550
16551         touch $DIR/$tfile
16552         ln $DIR/$tfile $DIR/$tfile.lnk
16553         touch $DIR/$tfile.new
16554         mv $DIR/$tfile.new $DIR/$tfile
16555         local fid1=$($LFS path2fid $DIR/$tfile)
16556         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
16557         local path1=$($LFS fid2path $FSNAME "$fid1")
16558         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
16559         local path2=$($LFS fid2path $FSNAME "$fid2")
16560         [ $tfile.lnk == $path2 ] ||
16561                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
16562         rm -f $DIR/$tfile*
16563 }
16564 run_test 238 "Verify linkea consistency"
16565
16566 test_239A() { # was test_239
16567         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16568                 skip "Need MDS version at least 2.5.60"
16569
16570         local list=$(comma_list $(mdts_nodes))
16571
16572         mkdir -p $DIR/$tdir
16573         createmany -o $DIR/$tdir/f- 5000
16574         unlinkmany $DIR/$tdir/f- 5000
16575         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16576                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16577         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16578                         osp.*MDT*.sync_in_flight" | calc_sum)
16579         [ "$changes" -eq 0 ] || error "$changes not synced"
16580 }
16581 run_test 239A "osp_sync test"
16582
16583 test_239a() { #LU-5297
16584         remote_mds_nodsh && skip "remote MDS with nodsh"
16585
16586         touch $DIR/$tfile
16587         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16588         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16589         chgrp $RUNAS_GID $DIR/$tfile
16590         wait_delete_completed
16591 }
16592 run_test 239a "process invalid osp sync record correctly"
16593
16594 test_239b() { #LU-5297
16595         remote_mds_nodsh && skip "remote MDS with nodsh"
16596
16597         touch $DIR/$tfile1
16598         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16599         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16600         chgrp $RUNAS_GID $DIR/$tfile1
16601         wait_delete_completed
16602         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16603         touch $DIR/$tfile2
16604         chgrp $RUNAS_GID $DIR/$tfile2
16605         wait_delete_completed
16606 }
16607 run_test 239b "process osp sync record with ENOMEM error correctly"
16608
16609 test_240() {
16610         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16611         remote_mds_nodsh && skip "remote MDS with nodsh"
16612
16613         mkdir -p $DIR/$tdir
16614
16615         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16616                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16617         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16618                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16619
16620         umount_client $MOUNT || error "umount failed"
16621         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16622         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16623         mount_client $MOUNT || error "failed to mount client"
16624
16625         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16626         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16627 }
16628 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16629
16630 test_241_bio() {
16631         local count=$1
16632         local bsize=$2
16633
16634         for LOOP in $(seq $count); do
16635                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16636                 cancel_lru_locks $OSC || true
16637         done
16638 }
16639
16640 test_241_dio() {
16641         local count=$1
16642         local bsize=$2
16643
16644         for LOOP in $(seq $1); do
16645                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16646                         2>/dev/null
16647         done
16648 }
16649
16650 test_241a() { # was test_241
16651         local bsize=$PAGE_SIZE
16652
16653         (( bsize < 40960 )) && bsize=40960
16654         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16655         ls -la $DIR/$tfile
16656         cancel_lru_locks $OSC
16657         test_241_bio 1000 $bsize &
16658         PID=$!
16659         test_241_dio 1000 $bsize
16660         wait $PID
16661 }
16662 run_test 241a "bio vs dio"
16663
16664 test_241b() {
16665         local bsize=$PAGE_SIZE
16666
16667         (( bsize < 40960 )) && bsize=40960
16668         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16669         ls -la $DIR/$tfile
16670         test_241_dio 1000 $bsize &
16671         PID=$!
16672         test_241_dio 1000 $bsize
16673         wait $PID
16674 }
16675 run_test 241b "dio vs dio"
16676
16677 test_242() {
16678         remote_mds_nodsh && skip "remote MDS with nodsh"
16679
16680         mkdir -p $DIR/$tdir
16681         touch $DIR/$tdir/$tfile
16682
16683         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16684         do_facet mds1 lctl set_param fail_loc=0x105
16685         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16686
16687         do_facet mds1 lctl set_param fail_loc=0
16688         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16689 }
16690 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16691
16692 test_243()
16693 {
16694         test_mkdir $DIR/$tdir
16695         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16696 }
16697 run_test 243 "various group lock tests"
16698
16699 test_244()
16700 {
16701         test_mkdir $DIR/$tdir
16702         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16703         sendfile_grouplock $DIR/$tdir/$tfile || \
16704                 error "sendfile+grouplock failed"
16705         rm -rf $DIR/$tdir
16706 }
16707 run_test 244 "sendfile with group lock tests"
16708
16709 test_245() {
16710         local flagname="multi_mod_rpcs"
16711         local connect_data_name="max_mod_rpcs"
16712         local out
16713
16714         # check if multiple modify RPCs flag is set
16715         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16716                 grep "connect_flags:")
16717         echo "$out"
16718
16719         echo "$out" | grep -qw $flagname
16720         if [ $? -ne 0 ]; then
16721                 echo "connect flag $flagname is not set"
16722                 return
16723         fi
16724
16725         # check if multiple modify RPCs data is set
16726         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16727         echo "$out"
16728
16729         echo "$out" | grep -qw $connect_data_name ||
16730                 error "import should have connect data $connect_data_name"
16731 }
16732 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16733
16734 test_246() { # LU-7371
16735         remote_ost_nodsh && skip "remote OST with nodsh"
16736         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16737                 skip "Need OST version >= 2.7.62"
16738
16739         do_facet ost1 $LCTL set_param fail_val=4095
16740 #define OBD_FAIL_OST_READ_SIZE          0x234
16741         do_facet ost1 $LCTL set_param fail_loc=0x234
16742         $LFS setstripe $DIR/$tfile -i 0 -c 1
16743         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16744         cancel_lru_locks $FSNAME-OST0000
16745         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16746 }
16747 run_test 246 "Read file of size 4095 should return right length"
16748
16749 cleanup_247() {
16750         local submount=$1
16751
16752         trap 0
16753         umount_client $submount
16754         rmdir $submount
16755 }
16756
16757 test_247a() {
16758         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16759                 grep -q subtree ||
16760                 skip_env "Fileset feature is not supported"
16761
16762         local submount=${MOUNT}_$tdir
16763
16764         mkdir $MOUNT/$tdir
16765         mkdir -p $submount || error "mkdir $submount failed"
16766         FILESET="$FILESET/$tdir" mount_client $submount ||
16767                 error "mount $submount failed"
16768         trap "cleanup_247 $submount" EXIT
16769         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16770         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16771                 error "read $MOUNT/$tdir/$tfile failed"
16772         cleanup_247 $submount
16773 }
16774 run_test 247a "mount subdir as fileset"
16775
16776 test_247b() {
16777         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16778                 skip_env "Fileset feature is not supported"
16779
16780         local submount=${MOUNT}_$tdir
16781
16782         rm -rf $MOUNT/$tdir
16783         mkdir -p $submount || error "mkdir $submount failed"
16784         SKIP_FILESET=1
16785         FILESET="$FILESET/$tdir" mount_client $submount &&
16786                 error "mount $submount should fail"
16787         rmdir $submount
16788 }
16789 run_test 247b "mount subdir that dose not exist"
16790
16791 test_247c() {
16792         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16793                 skip_env "Fileset feature is not supported"
16794
16795         local submount=${MOUNT}_$tdir
16796
16797         mkdir -p $MOUNT/$tdir/dir1
16798         mkdir -p $submount || error "mkdir $submount failed"
16799         trap "cleanup_247 $submount" EXIT
16800         FILESET="$FILESET/$tdir" mount_client $submount ||
16801                 error "mount $submount failed"
16802         local fid=$($LFS path2fid $MOUNT/)
16803         $LFS fid2path $submount $fid && error "fid2path should fail"
16804         cleanup_247 $submount
16805 }
16806 run_test 247c "running fid2path outside root"
16807
16808 test_247d() {
16809         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16810                 skip "Fileset feature is not supported"
16811
16812         local submount=${MOUNT}_$tdir
16813
16814         mkdir -p $MOUNT/$tdir/dir1
16815         mkdir -p $submount || error "mkdir $submount failed"
16816         FILESET="$FILESET/$tdir" mount_client $submount ||
16817                 error "mount $submount failed"
16818         trap "cleanup_247 $submount" EXIT
16819         local fid=$($LFS path2fid $submount/dir1)
16820         $LFS fid2path $submount $fid || error "fid2path should succeed"
16821         cleanup_247 $submount
16822 }
16823 run_test 247d "running fid2path inside root"
16824
16825 # LU-8037
16826 test_247e() {
16827         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16828                 grep -q subtree ||
16829                 skip "Fileset feature is not supported"
16830
16831         local submount=${MOUNT}_$tdir
16832
16833         mkdir $MOUNT/$tdir
16834         mkdir -p $submount || error "mkdir $submount failed"
16835         FILESET="$FILESET/.." mount_client $submount &&
16836                 error "mount $submount should fail"
16837         rmdir $submount
16838 }
16839 run_test 247e "mount .. as fileset"
16840
16841 test_248() {
16842         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16843         [ -z "$fast_read_sav" ] && skip "no fast read support"
16844
16845         # create a large file for fast read verification
16846         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16847
16848         # make sure the file is created correctly
16849         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16850                 { rm -f $DIR/$tfile; skip "file creation error"; }
16851
16852         echo "Test 1: verify that fast read is 4 times faster on cache read"
16853
16854         # small read with fast read enabled
16855         $LCTL set_param -n llite.*.fast_read=1
16856         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16857                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16858                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16859         # small read with fast read disabled
16860         $LCTL set_param -n llite.*.fast_read=0
16861         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16862                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16863                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16864
16865         # verify that fast read is 4 times faster for cache read
16866         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16867                 error_not_in_vm "fast read was not 4 times faster: " \
16868                            "$t_fast vs $t_slow"
16869
16870         echo "Test 2: verify the performance between big and small read"
16871         $LCTL set_param -n llite.*.fast_read=1
16872
16873         # 1k non-cache read
16874         cancel_lru_locks osc
16875         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16876                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16877                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16878
16879         # 1M non-cache read
16880         cancel_lru_locks osc
16881         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16882                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16883                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16884
16885         # verify that big IO is not 4 times faster than small IO
16886         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16887                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16888
16889         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16890         rm -f $DIR/$tfile
16891 }
16892 run_test 248 "fast read verification"
16893
16894 test_249() { # LU-7890
16895         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16896                 skip "Need at least version 2.8.54"
16897
16898         rm -f $DIR/$tfile
16899         $LFS setstripe -c 1 $DIR/$tfile
16900         # Offset 2T == 4k * 512M
16901         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16902                 error "dd to 2T offset failed"
16903 }
16904 run_test 249 "Write above 2T file size"
16905
16906 test_250() {
16907         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16908          && skip "no 16TB file size limit on ZFS"
16909
16910         $LFS setstripe -c 1 $DIR/$tfile
16911         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16912         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16913         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16914         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16915                 conv=notrunc,fsync && error "append succeeded"
16916         return 0
16917 }
16918 run_test 250 "Write above 16T limit"
16919
16920 test_251() {
16921         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16922
16923         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16924         #Skip once - writing the first stripe will succeed
16925         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16926         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16927                 error "short write happened"
16928
16929         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16930         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16931                 error "short read happened"
16932
16933         rm -f $DIR/$tfile
16934 }
16935 run_test 251 "Handling short read and write correctly"
16936
16937 test_252() {
16938         remote_mds_nodsh && skip "remote MDS with nodsh"
16939         remote_ost_nodsh && skip "remote OST with nodsh"
16940         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
16941                 skip_env "ldiskfs only test"
16942         fi
16943
16944         local tgt
16945         local dev
16946         local out
16947         local uuid
16948         local num
16949         local gen
16950
16951         # check lr_reader on OST0000
16952         tgt=ost1
16953         dev=$(facet_device $tgt)
16954         out=$(do_facet $tgt $LR_READER $dev)
16955         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16956         echo "$out"
16957         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16958         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16959                 error "Invalid uuid returned by $LR_READER on target $tgt"
16960         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16961
16962         # check lr_reader -c on MDT0000
16963         tgt=mds1
16964         dev=$(facet_device $tgt)
16965         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16966                 skip "$LR_READER does not support additional options"
16967         fi
16968         out=$(do_facet $tgt $LR_READER -c $dev)
16969         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16970         echo "$out"
16971         num=$(echo "$out" | grep -c "mdtlov")
16972         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16973                 error "Invalid number of mdtlov clients returned by $LR_READER"
16974         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16975
16976         # check lr_reader -cr on MDT0000
16977         out=$(do_facet $tgt $LR_READER -cr $dev)
16978         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16979         echo "$out"
16980         echo "$out" | grep -q "^reply_data:$" ||
16981                 error "$LR_READER should have returned 'reply_data' section"
16982         num=$(echo "$out" | grep -c "client_generation")
16983         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16984 }
16985 run_test 252 "check lr_reader tool"
16986
16987 test_253() {
16988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16989         remote_mds_nodsh && skip "remote MDS with nodsh"
16990         remote_mgs_nodsh && skip "remote MGS with nodsh"
16991
16992         local ostidx=0
16993         local rc=0
16994         local ost_name=$(ostname_from_index $ostidx)
16995
16996         # on the mdt's osc
16997         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16998         do_facet $SINGLEMDS $LCTL get_param -n \
16999                 osp.$mdtosc_proc1.reserved_mb_high ||
17000                 skip  "remote MDS does not support reserved_mb_high"
17001
17002         rm -rf $DIR/$tdir
17003         wait_mds_ost_sync
17004         wait_delete_completed
17005         mkdir $DIR/$tdir
17006
17007         if ! combined_mgs_mds ; then
17008                 mount_mgs_client
17009         fi
17010         pool_add $TESTNAME || error "Pool creation failed"
17011         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
17012
17013         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
17014                 error "Setstripe failed"
17015
17016         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
17017
17018         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
17019                     grep "watermarks")
17020         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
17021
17022         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17023                         osp.$mdtosc_proc1.prealloc_status)
17024         echo "prealloc_status $oa_status"
17025
17026         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
17027                 error "File creation should fail"
17028
17029         #object allocation was stopped, but we still able to append files
17030         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
17031                 oflag=append || error "Append failed"
17032
17033         rm -f $DIR/$tdir/$tfile.0
17034
17035         # For this test, we want to delete the files we created to go out of
17036         # space but leave the watermark, so we remain nearly out of space
17037         ost_watermarks_enospc_delete_files $tfile $ostidx
17038
17039         wait_delete_completed
17040
17041         sleep_maxage
17042
17043         for i in $(seq 10 12); do
17044                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
17045                         2>/dev/null || error "File creation failed after rm"
17046         done
17047
17048         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17049                         osp.$mdtosc_proc1.prealloc_status)
17050         echo "prealloc_status $oa_status"
17051
17052         if (( oa_status != 0 )); then
17053                 error "Object allocation still disable after rm"
17054         fi
17055
17056         if ! combined_mgs_mds ; then
17057                 umount_mgs_client
17058         fi
17059 }
17060 run_test 253 "Check object allocation limit"
17061
17062 test_254() {
17063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17064         remote_mds_nodsh && skip "remote MDS with nodsh"
17065         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17066                 skip "MDS does not support changelog_size"
17067
17068         local cl_user
17069         local MDT0=$(facet_svc $SINGLEMDS)
17070
17071         changelog_register || error "changelog_register failed"
17072
17073         changelog_clear 0 || error "changelog_clear failed"
17074
17075         local size1=$(do_facet $SINGLEMDS \
17076                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17077         echo "Changelog size $size1"
17078
17079         rm -rf $DIR/$tdir
17080         $LFS mkdir -i 0 $DIR/$tdir
17081         # change something
17082         mkdir -p $DIR/$tdir/pics/2008/zachy
17083         touch $DIR/$tdir/pics/2008/zachy/timestamp
17084         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17085         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17086         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17087         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17088         rm $DIR/$tdir/pics/desktop.jpg
17089
17090         local size2=$(do_facet $SINGLEMDS \
17091                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17092         echo "Changelog size after work $size2"
17093
17094         (( $size2 > $size1 )) ||
17095                 error "new Changelog size=$size2 less than old size=$size1"
17096 }
17097 run_test 254 "Check changelog size"
17098
17099 ladvise_no_type()
17100 {
17101         local type=$1
17102         local file=$2
17103
17104         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17105                 awk -F: '{print $2}' | grep $type > /dev/null
17106         if [ $? -ne 0 ]; then
17107                 return 0
17108         fi
17109         return 1
17110 }
17111
17112 ladvise_no_ioctl()
17113 {
17114         local file=$1
17115
17116         lfs ladvise -a willread $file > /dev/null 2>&1
17117         if [ $? -eq 0 ]; then
17118                 return 1
17119         fi
17120
17121         lfs ladvise -a willread $file 2>&1 |
17122                 grep "Inappropriate ioctl for device" > /dev/null
17123         if [ $? -eq 0 ]; then
17124                 return 0
17125         fi
17126         return 1
17127 }
17128
17129 percent() {
17130         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17131 }
17132
17133 # run a random read IO workload
17134 # usage: random_read_iops <filename> <filesize> <iosize>
17135 random_read_iops() {
17136         local file=$1
17137         local fsize=$2
17138         local iosize=${3:-4096}
17139
17140         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17141                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17142 }
17143
17144 drop_file_oss_cache() {
17145         local file="$1"
17146         local nodes="$2"
17147
17148         $LFS ladvise -a dontneed $file 2>/dev/null ||
17149                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17150 }
17151
17152 ladvise_willread_performance()
17153 {
17154         local repeat=10
17155         local average_origin=0
17156         local average_cache=0
17157         local average_ladvise=0
17158
17159         for ((i = 1; i <= $repeat; i++)); do
17160                 echo "Iter $i/$repeat: reading without willread hint"
17161                 cancel_lru_locks osc
17162                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17163                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17164                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17165                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17166
17167                 cancel_lru_locks osc
17168                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17169                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17170                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17171
17172                 cancel_lru_locks osc
17173                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17174                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17175                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17176                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17177                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17178         done
17179         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17180         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17181         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17182
17183         speedup_cache=$(percent $average_cache $average_origin)
17184         speedup_ladvise=$(percent $average_ladvise $average_origin)
17185
17186         echo "Average uncached read: $average_origin"
17187         echo "Average speedup with OSS cached read: " \
17188                 "$average_cache = +$speedup_cache%"
17189         echo "Average speedup with ladvise willread: " \
17190                 "$average_ladvise = +$speedup_ladvise%"
17191
17192         local lowest_speedup=20
17193         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17194                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17195                         "got $average_cache%. Skipping ladvise willread check."
17196                 return 0
17197         fi
17198
17199         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17200         # it is still good to run until then to exercise 'ladvise willread'
17201         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17202                 [ "$ost1_FSTYPE" = "zfs" ] &&
17203                 echo "osd-zfs does not support dontneed or drop_caches" &&
17204                 return 0
17205
17206         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17207         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17208                 error_not_in_vm "Speedup with willread is less than " \
17209                         "$lowest_speedup%, got $average_ladvise%"
17210 }
17211
17212 test_255a() {
17213         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17214                 skip "lustre < 2.8.54 does not support ladvise "
17215         remote_ost_nodsh && skip "remote OST with nodsh"
17216
17217         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17218
17219         ladvise_no_type willread $DIR/$tfile &&
17220                 skip "willread ladvise is not supported"
17221
17222         ladvise_no_ioctl $DIR/$tfile &&
17223                 skip "ladvise ioctl is not supported"
17224
17225         local size_mb=100
17226         local size=$((size_mb * 1048576))
17227         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17228                 error "dd to $DIR/$tfile failed"
17229
17230         lfs ladvise -a willread $DIR/$tfile ||
17231                 error "Ladvise failed with no range argument"
17232
17233         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17234                 error "Ladvise failed with no -l or -e argument"
17235
17236         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17237                 error "Ladvise failed with only -e argument"
17238
17239         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17240                 error "Ladvise failed with only -l argument"
17241
17242         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17243                 error "End offset should not be smaller than start offset"
17244
17245         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17246                 error "End offset should not be equal to start offset"
17247
17248         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17249                 error "Ladvise failed with overflowing -s argument"
17250
17251         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17252                 error "Ladvise failed with overflowing -e argument"
17253
17254         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17255                 error "Ladvise failed with overflowing -l argument"
17256
17257         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17258                 error "Ladvise succeeded with conflicting -l and -e arguments"
17259
17260         echo "Synchronous ladvise should wait"
17261         local delay=4
17262 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17263         do_nodes $(comma_list $(osts_nodes)) \
17264                 $LCTL set_param fail_val=$delay fail_loc=0x237
17265
17266         local start_ts=$SECONDS
17267         lfs ladvise -a willread $DIR/$tfile ||
17268                 error "Ladvise failed with no range argument"
17269         local end_ts=$SECONDS
17270         local inteval_ts=$((end_ts - start_ts))
17271
17272         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17273                 error "Synchronous advice didn't wait reply"
17274         fi
17275
17276         echo "Asynchronous ladvise shouldn't wait"
17277         local start_ts=$SECONDS
17278         lfs ladvise -a willread -b $DIR/$tfile ||
17279                 error "Ladvise failed with no range argument"
17280         local end_ts=$SECONDS
17281         local inteval_ts=$((end_ts - start_ts))
17282
17283         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17284                 error "Asynchronous advice blocked"
17285         fi
17286
17287         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
17288         ladvise_willread_performance
17289 }
17290 run_test 255a "check 'lfs ladvise -a willread'"
17291
17292 facet_meminfo() {
17293         local facet=$1
17294         local info=$2
17295
17296         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
17297 }
17298
17299 test_255b() {
17300         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17301                 skip "lustre < 2.8.54 does not support ladvise "
17302         remote_ost_nodsh && skip "remote OST with nodsh"
17303
17304         lfs setstripe -c 1 -i 0 $DIR/$tfile
17305
17306         ladvise_no_type dontneed $DIR/$tfile &&
17307                 skip "dontneed ladvise is not supported"
17308
17309         ladvise_no_ioctl $DIR/$tfile &&
17310                 skip "ladvise ioctl is not supported"
17311
17312         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17313                 [ "$ost1_FSTYPE" = "zfs" ] &&
17314                 skip "zfs-osd does not support 'ladvise dontneed'"
17315
17316         local size_mb=100
17317         local size=$((size_mb * 1048576))
17318         # In order to prevent disturbance of other processes, only check 3/4
17319         # of the memory usage
17320         local kibibytes=$((size_mb * 1024 * 3 / 4))
17321
17322         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17323                 error "dd to $DIR/$tfile failed"
17324
17325         #force write to complete before dropping OST cache & checking memory
17326         sync
17327
17328         local total=$(facet_meminfo ost1 MemTotal)
17329         echo "Total memory: $total KiB"
17330
17331         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
17332         local before_read=$(facet_meminfo ost1 Cached)
17333         echo "Cache used before read: $before_read KiB"
17334
17335         lfs ladvise -a willread $DIR/$tfile ||
17336                 error "Ladvise willread failed"
17337         local after_read=$(facet_meminfo ost1 Cached)
17338         echo "Cache used after read: $after_read KiB"
17339
17340         lfs ladvise -a dontneed $DIR/$tfile ||
17341                 error "Ladvise dontneed again failed"
17342         local no_read=$(facet_meminfo ost1 Cached)
17343         echo "Cache used after dontneed ladvise: $no_read KiB"
17344
17345         if [ $total -lt $((before_read + kibibytes)) ]; then
17346                 echo "Memory is too small, abort checking"
17347                 return 0
17348         fi
17349
17350         if [ $((before_read + kibibytes)) -gt $after_read ]; then
17351                 error "Ladvise willread should use more memory" \
17352                         "than $kibibytes KiB"
17353         fi
17354
17355         if [ $((no_read + kibibytes)) -gt $after_read ]; then
17356                 error "Ladvise dontneed should release more memory" \
17357                         "than $kibibytes KiB"
17358         fi
17359 }
17360 run_test 255b "check 'lfs ladvise -a dontneed'"
17361
17362 test_255c() {
17363         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
17364                 skip "lustre < 2.10.53 does not support lockahead"
17365
17366         local count
17367         local new_count
17368         local difference
17369         local i
17370         local rc
17371
17372         test_mkdir -p $DIR/$tdir
17373         $LFS setstripe -i 0 -c 1 $DIR/$tdir
17374
17375         #test 10 returns only success/failure
17376         i=10
17377         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17378         rc=$?
17379         if [ $rc -eq 255 ]; then
17380                 error "Ladvise test${i} failed, ${rc}"
17381         fi
17382
17383         #test 11 counts lock enqueue requests, all others count new locks
17384         i=11
17385         count=$(do_facet ost1 \
17386                 $LCTL get_param -n ost.OSS.ost.stats)
17387         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
17388
17389         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17390         rc=$?
17391         if [ $rc -eq 255 ]; then
17392                 error "Ladvise test${i} failed, ${rc}"
17393         fi
17394
17395         new_count=$(do_facet ost1 \
17396                 $LCTL get_param -n ost.OSS.ost.stats)
17397         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
17398                    awk '{ print $2 }')
17399
17400         difference="$((new_count - count))"
17401         if [ $difference -ne $rc ]; then
17402                 error "Ladvise test${i}, bad enqueue count, returned " \
17403                       "${rc}, actual ${difference}"
17404         fi
17405
17406         for i in $(seq 12 21); do
17407                 # If we do not do this, we run the risk of having too many
17408                 # locks and starting lock cancellation while we are checking
17409                 # lock counts.
17410                 cancel_lru_locks osc
17411
17412                 count=$($LCTL get_param -n \
17413                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17414
17415                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
17416                 rc=$?
17417                 if [ $rc -eq 255 ]; then
17418                         error "Ladvise test ${i} failed, ${rc}"
17419                 fi
17420
17421                 new_count=$($LCTL get_param -n \
17422                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17423                 difference="$((new_count - count))"
17424
17425                 # Test 15 output is divided by 100 to map down to valid return
17426                 if [ $i -eq 15 ]; then
17427                         rc="$((rc * 100))"
17428                 fi
17429
17430                 if [ $difference -ne $rc ]; then
17431                         error "Ladvise test ${i}, bad lock count, returned " \
17432                               "${rc}, actual ${difference}"
17433                 fi
17434         done
17435
17436         #test 22 returns only success/failure
17437         i=22
17438         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17439         rc=$?
17440         if [ $rc -eq 255 ]; then
17441                 error "Ladvise test${i} failed, ${rc}"
17442         fi
17443 }
17444 run_test 255c "suite of ladvise lockahead tests"
17445
17446 test_256() {
17447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17448         remote_mds_nodsh && skip "remote MDS with nodsh"
17449         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17450         changelog_users $SINGLEMDS | grep "^cl" &&
17451                 skip "active changelog user"
17452
17453         local cl_user
17454         local cat_sl
17455         local mdt_dev
17456
17457         mdt_dev=$(mdsdevname 1)
17458         echo $mdt_dev
17459
17460         changelog_register || error "changelog_register failed"
17461
17462         rm -rf $DIR/$tdir
17463         mkdir -p $DIR/$tdir
17464
17465         changelog_clear 0 || error "changelog_clear failed"
17466
17467         # change something
17468         touch $DIR/$tdir/{1..10}
17469
17470         # stop the MDT
17471         stop $SINGLEMDS || error "Fail to stop MDT"
17472
17473         # remount the MDT
17474
17475         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
17476
17477         #after mount new plainllog is used
17478         touch $DIR/$tdir/{11..19}
17479         local tmpfile=$(mktemp -u $tfile.XXXXXX)
17480         cat_sl=$(do_facet $SINGLEMDS "sync; \
17481                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17482                  llog_reader $tmpfile | grep -c type=1064553b")
17483         do_facet $SINGLEMDS llog_reader $tmpfile
17484
17485         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
17486
17487         changelog_clear 0 || error "changelog_clear failed"
17488
17489         cat_sl=$(do_facet $SINGLEMDS "sync; \
17490                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17491                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
17492
17493         if (( cat_sl == 2 )); then
17494                 error "Empty plain llog was not deleted from changelog catalog"
17495         elif (( cat_sl != 1 )); then
17496                 error "Active plain llog shouldn't be deleted from catalog"
17497         fi
17498 }
17499 run_test 256 "Check llog delete for empty and not full state"
17500
17501 test_257() {
17502         remote_mds_nodsh && skip "remote MDS with nodsh"
17503         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
17504                 skip "Need MDS version at least 2.8.55"
17505
17506         test_mkdir $DIR/$tdir
17507
17508         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
17509                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
17510         stat $DIR/$tdir
17511
17512 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17513         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17514         local facet=mds$((mdtidx + 1))
17515         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17516         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17517
17518         stop $facet || error "stop MDS failed"
17519         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17520                 error "start MDS fail"
17521         wait_recovery_complete $facet
17522 }
17523 run_test 257 "xattr locks are not lost"
17524
17525 # Verify we take the i_mutex when security requires it
17526 test_258a() {
17527 #define OBD_FAIL_IMUTEX_SEC 0x141c
17528         $LCTL set_param fail_loc=0x141c
17529         touch $DIR/$tfile
17530         chmod u+s $DIR/$tfile
17531         chmod a+rwx $DIR/$tfile
17532         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17533         RC=$?
17534         if [ $RC -ne 0 ]; then
17535                 error "error, failed to take i_mutex, rc=$?"
17536         fi
17537         rm -f $DIR/$tfile
17538 }
17539 run_test 258a "verify i_mutex security behavior when suid attributes is set"
17540
17541 # Verify we do NOT take the i_mutex in the normal case
17542 test_258b() {
17543 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17544         $LCTL set_param fail_loc=0x141d
17545         touch $DIR/$tfile
17546         chmod a+rwx $DIR
17547         chmod a+rw $DIR/$tfile
17548         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17549         RC=$?
17550         if [ $RC -ne 0 ]; then
17551                 error "error, took i_mutex unnecessarily, rc=$?"
17552         fi
17553         rm -f $DIR/$tfile
17554
17555 }
17556 run_test 258b "verify i_mutex security behavior"
17557
17558 test_259() {
17559         local file=$DIR/$tfile
17560         local before
17561         local after
17562
17563         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17564
17565         stack_trap "rm -f $file" EXIT
17566
17567         wait_delete_completed
17568         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17569         echo "before: $before"
17570
17571         $LFS setstripe -i 0 -c 1 $file
17572         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17573         sync_all_data
17574         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17575         echo "after write: $after"
17576
17577 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17578         do_facet ost1 $LCTL set_param fail_loc=0x2301
17579         $TRUNCATE $file 0
17580         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17581         echo "after truncate: $after"
17582
17583         stop ost1
17584         do_facet ost1 $LCTL set_param fail_loc=0
17585         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17586         sleep 2
17587         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17588         echo "after restart: $after"
17589         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17590                 error "missing truncate?"
17591
17592         return 0
17593 }
17594 run_test 259 "crash at delayed truncate"
17595
17596 test_260() {
17597 #define OBD_FAIL_MDC_CLOSE               0x806
17598         $LCTL set_param fail_loc=0x80000806
17599         touch $DIR/$tfile
17600
17601 }
17602 run_test 260 "Check mdc_close fail"
17603
17604 ### Data-on-MDT sanity tests ###
17605 test_270a() {
17606         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17607                 skip "Need MDS version at least 2.10.55 for DoM"
17608
17609         # create DoM file
17610         local dom=$DIR/$tdir/dom_file
17611         local tmp=$DIR/$tdir/tmp_file
17612
17613         mkdir -p $DIR/$tdir
17614
17615         # basic checks for DoM component creation
17616         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17617                 error "Can set MDT layout to non-first entry"
17618
17619         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17620                 error "Can define multiple entries as MDT layout"
17621
17622         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17623
17624         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17625         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17626         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17627
17628         local mdtidx=$($LFS getstripe -m $dom)
17629         local mdtname=MDT$(printf %04x $mdtidx)
17630         local facet=mds$((mdtidx + 1))
17631         local space_check=1
17632
17633         # Skip free space checks with ZFS
17634         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17635
17636         # write
17637         sync
17638         local size_tmp=$((65536 * 3))
17639         local mdtfree1=$(do_facet $facet \
17640                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17641
17642         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17643         # check also direct IO along write
17644         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17645         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17646         sync
17647         cmp $tmp $dom || error "file data is different"
17648         [ $(stat -c%s $dom) == $size_tmp ] ||
17649                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17650         if [ $space_check == 1 ]; then
17651                 local mdtfree2=$(do_facet $facet \
17652                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17653
17654                 # increase in usage from by $size_tmp
17655                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17656                         error "MDT free space wrong after write: " \
17657                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17658         fi
17659
17660         # truncate
17661         local size_dom=10000
17662
17663         $TRUNCATE $dom $size_dom
17664         [ $(stat -c%s $dom) == $size_dom ] ||
17665                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17666         if [ $space_check == 1 ]; then
17667                 mdtfree1=$(do_facet $facet \
17668                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17669                 # decrease in usage from $size_tmp to new $size_dom
17670                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17671                   $(((size_tmp - size_dom) / 1024)) ] ||
17672                         error "MDT free space is wrong after truncate: " \
17673                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17674         fi
17675
17676         # append
17677         cat $tmp >> $dom
17678         sync
17679         size_dom=$((size_dom + size_tmp))
17680         [ $(stat -c%s $dom) == $size_dom ] ||
17681                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17682         if [ $space_check == 1 ]; then
17683                 mdtfree2=$(do_facet $facet \
17684                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17685                 # increase in usage by $size_tmp from previous
17686                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17687                         error "MDT free space is wrong after append: " \
17688                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17689         fi
17690
17691         # delete
17692         rm $dom
17693         if [ $space_check == 1 ]; then
17694                 mdtfree1=$(do_facet $facet \
17695                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17696                 # decrease in usage by $size_dom from previous
17697                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17698                         error "MDT free space is wrong after removal: " \
17699                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17700         fi
17701
17702         # combined striping
17703         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17704                 error "Can't create DoM + OST striping"
17705
17706         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17707         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17708         # check also direct IO along write
17709         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17710         sync
17711         cmp $tmp $dom || error "file data is different"
17712         [ $(stat -c%s $dom) == $size_tmp ] ||
17713                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17714         rm $dom $tmp
17715
17716         return 0
17717 }
17718 run_test 270a "DoM: basic functionality tests"
17719
17720 test_270b() {
17721         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17722                 skip "Need MDS version at least 2.10.55"
17723
17724         local dom=$DIR/$tdir/dom_file
17725         local max_size=1048576
17726
17727         mkdir -p $DIR/$tdir
17728         $LFS setstripe -E $max_size -L mdt $dom
17729
17730         # truncate over the limit
17731         $TRUNCATE $dom $(($max_size + 1)) &&
17732                 error "successful truncate over the maximum size"
17733         # write over the limit
17734         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17735                 error "successful write over the maximum size"
17736         # append over the limit
17737         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17738         echo "12345" >> $dom && error "successful append over the maximum size"
17739         rm $dom
17740
17741         return 0
17742 }
17743 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17744
17745 test_270c() {
17746         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17747                 skip "Need MDS version at least 2.10.55"
17748
17749         mkdir -p $DIR/$tdir
17750         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17751
17752         # check files inherit DoM EA
17753         touch $DIR/$tdir/first
17754         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17755                 error "bad pattern"
17756         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17757                 error "bad stripe count"
17758         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17759                 error "bad stripe size"
17760
17761         # check directory inherits DoM EA and uses it as default
17762         mkdir $DIR/$tdir/subdir
17763         touch $DIR/$tdir/subdir/second
17764         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17765                 error "bad pattern in sub-directory"
17766         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17767                 error "bad stripe count in sub-directory"
17768         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17769                 error "bad stripe size in sub-directory"
17770         return 0
17771 }
17772 run_test 270c "DoM: DoM EA inheritance tests"
17773
17774 test_270d() {
17775         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17776                 skip "Need MDS version at least 2.10.55"
17777
17778         mkdir -p $DIR/$tdir
17779         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17780
17781         # inherit default DoM striping
17782         mkdir $DIR/$tdir/subdir
17783         touch $DIR/$tdir/subdir/f1
17784
17785         # change default directory striping
17786         $LFS setstripe -c 1 $DIR/$tdir/subdir
17787         touch $DIR/$tdir/subdir/f2
17788         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17789                 error "wrong default striping in file 2"
17790         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17791                 error "bad pattern in file 2"
17792         return 0
17793 }
17794 run_test 270d "DoM: change striping from DoM to RAID0"
17795
17796 test_270e() {
17797         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17798                 skip "Need MDS version at least 2.10.55"
17799
17800         mkdir -p $DIR/$tdir/dom
17801         mkdir -p $DIR/$tdir/norm
17802         DOMFILES=20
17803         NORMFILES=10
17804         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17805         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17806
17807         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17808         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17809
17810         # find DoM files by layout
17811         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17812         [ $NUM -eq  $DOMFILES ] ||
17813                 error "lfs find -L: found $NUM, expected $DOMFILES"
17814         echo "Test 1: lfs find 20 DOM files by layout: OK"
17815
17816         # there should be 1 dir with default DOM striping
17817         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17818         [ $NUM -eq  1 ] ||
17819                 error "lfs find -L: found $NUM, expected 1 dir"
17820         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17821
17822         # find DoM files by stripe size
17823         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17824         [ $NUM -eq  $DOMFILES ] ||
17825                 error "lfs find -S: found $NUM, expected $DOMFILES"
17826         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17827
17828         # find files by stripe offset except DoM files
17829         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17830         [ $NUM -eq  $NORMFILES ] ||
17831                 error "lfs find -i: found $NUM, expected $NORMFILES"
17832         echo "Test 5: lfs find no DOM files by stripe index: OK"
17833         return 0
17834 }
17835 run_test 270e "DoM: lfs find with DoM files test"
17836
17837 test_270f() {
17838         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17839                 skip "Need MDS version at least 2.10.55"
17840
17841         local mdtname=${FSNAME}-MDT0000-mdtlov
17842         local dom=$DIR/$tdir/dom_file
17843         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17844                                                 lod.$mdtname.dom_stripesize)
17845         local dom_limit=131072
17846
17847         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17848         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17849                                                 lod.$mdtname.dom_stripesize)
17850         [ ${dom_limit} -eq ${dom_current} ] ||
17851                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17852
17853         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17854         $LFS setstripe -d $DIR/$tdir
17855         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17856                 error "Can't set directory default striping"
17857
17858         # exceed maximum stripe size
17859         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17860                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17861         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17862                 error "Able to create DoM component size more than LOD limit"
17863
17864         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17865         dom_current=$(do_facet mds1 $LCTL get_param -n \
17866                                                 lod.$mdtname.dom_stripesize)
17867         [ 0 -eq ${dom_current} ] ||
17868                 error "Can't set zero DoM stripe limit"
17869         rm $dom
17870
17871         # attempt to create DoM file on server with disabled DoM should
17872         # remove DoM entry from layout and be succeed
17873         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17874                 error "Can't create DoM file (DoM is disabled)"
17875         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17876                 error "File has DoM component while DoM is disabled"
17877         rm $dom
17878
17879         # attempt to create DoM file with only DoM stripe should return error
17880         $LFS setstripe -E $dom_limit -L mdt $dom &&
17881                 error "Able to create DoM-only file while DoM is disabled"
17882
17883         # too low values to be aligned with smallest stripe size 64K
17884         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17885         dom_current=$(do_facet mds1 $LCTL get_param -n \
17886                                                 lod.$mdtname.dom_stripesize)
17887         [ 30000 -eq ${dom_current} ] &&
17888                 error "Can set too small DoM stripe limit"
17889
17890         # 64K is a minimal stripe size in Lustre, expect limit of that size
17891         [ 65536 -eq ${dom_current} ] ||
17892                 error "Limit is not set to 64K but ${dom_current}"
17893
17894         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17895         dom_current=$(do_facet mds1 $LCTL get_param -n \
17896                                                 lod.$mdtname.dom_stripesize)
17897         echo $dom_current
17898         [ 2147483648 -eq ${dom_current} ] &&
17899                 error "Can set too large DoM stripe limit"
17900
17901         do_facet mds1 $LCTL set_param -n \
17902                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17903         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17904                 error "Can't create DoM component size after limit change"
17905         do_facet mds1 $LCTL set_param -n \
17906                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17907         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17908                 error "Can't create DoM file after limit decrease"
17909         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17910                 error "Can create big DoM component after limit decrease"
17911         touch ${dom}_def ||
17912                 error "Can't create file with old default layout"
17913
17914         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17915         return 0
17916 }
17917 run_test 270f "DoM: maximum DoM stripe size checks"
17918
17919 test_271a() {
17920         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17921                 skip "Need MDS version at least 2.10.55"
17922
17923         local dom=$DIR/$tdir/dom
17924
17925         mkdir -p $DIR/$tdir
17926
17927         $LFS setstripe -E 1024K -L mdt $dom
17928
17929         lctl set_param -n mdc.*.stats=clear
17930         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17931         cat $dom > /dev/null
17932         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17933         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17934         ls $dom
17935         rm -f $dom
17936 }
17937 run_test 271a "DoM: data is cached for read after write"
17938
17939 test_271b() {
17940         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17941                 skip "Need MDS version at least 2.10.55"
17942
17943         local dom=$DIR/$tdir/dom
17944
17945         mkdir -p $DIR/$tdir
17946
17947         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17948
17949         lctl set_param -n mdc.*.stats=clear
17950         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17951         cancel_lru_locks mdc
17952         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17953         # second stat to check size is cached on client
17954         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17955         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17956         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17957         rm -f $dom
17958 }
17959 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17960
17961 test_271ba() {
17962         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17963                 skip "Need MDS version at least 2.10.55"
17964
17965         local dom=$DIR/$tdir/dom
17966
17967         mkdir -p $DIR/$tdir
17968
17969         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17970
17971         lctl set_param -n mdc.*.stats=clear
17972         lctl set_param -n osc.*.stats=clear
17973         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17974         cancel_lru_locks mdc
17975         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17976         # second stat to check size is cached on client
17977         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17978         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17979         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17980         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17981         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17982         rm -f $dom
17983 }
17984 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17985
17986
17987 get_mdc_stats() {
17988         local mdtidx=$1
17989         local param=$2
17990         local mdt=MDT$(printf %04x $mdtidx)
17991
17992         if [ -z $param ]; then
17993                 lctl get_param -n mdc.*$mdt*.stats
17994         else
17995                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17996         fi
17997 }
17998
17999 test_271c() {
18000         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18001                 skip "Need MDS version at least 2.10.55"
18002
18003         local dom=$DIR/$tdir/dom
18004
18005         mkdir -p $DIR/$tdir
18006
18007         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18008
18009         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18010         local facet=mds$((mdtidx + 1))
18011
18012         cancel_lru_locks mdc
18013         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
18014         createmany -o $dom 1000
18015         lctl set_param -n mdc.*.stats=clear
18016         smalliomany -w $dom 1000 200
18017         get_mdc_stats $mdtidx
18018         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18019         # Each file has 1 open, 1 IO enqueues, total 2000
18020         # but now we have also +1 getxattr for security.capability, total 3000
18021         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
18022         unlinkmany $dom 1000
18023
18024         cancel_lru_locks mdc
18025         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
18026         createmany -o $dom 1000
18027         lctl set_param -n mdc.*.stats=clear
18028         smalliomany -w $dom 1000 200
18029         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18030         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
18031         # for OPEN and IO lock.
18032         [ $((enq - enq_2)) -ge 1000 ] ||
18033                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
18034         unlinkmany $dom 1000
18035         return 0
18036 }
18037 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
18038
18039 cleanup_271def_tests() {
18040         trap 0
18041         rm -f $1
18042 }
18043
18044 test_271d() {
18045         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18046                 skip "Need MDS version at least 2.10.57"
18047
18048         local dom=$DIR/$tdir/dom
18049         local tmp=$TMP/$tfile
18050         trap "cleanup_271def_tests $tmp" EXIT
18051
18052         mkdir -p $DIR/$tdir
18053
18054         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18055
18056         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18057
18058         cancel_lru_locks mdc
18059         dd if=/dev/urandom of=$tmp bs=1000 count=1
18060         dd if=$tmp of=$dom bs=1000 count=1
18061         cancel_lru_locks mdc
18062
18063         cat /etc/hosts >> $tmp
18064         lctl set_param -n mdc.*.stats=clear
18065
18066         # append data to the same file it should update local page
18067         echo "Append to the same page"
18068         cat /etc/hosts >> $dom
18069         local num=$(get_mdc_stats $mdtidx ost_read)
18070         local ra=$(get_mdc_stats $mdtidx req_active)
18071         local rw=$(get_mdc_stats $mdtidx req_waittime)
18072
18073         [ -z $num ] || error "$num READ RPC occured"
18074         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18075         echo "... DONE"
18076
18077         # compare content
18078         cmp $tmp $dom || error "file miscompare"
18079
18080         cancel_lru_locks mdc
18081         lctl set_param -n mdc.*.stats=clear
18082
18083         echo "Open and read file"
18084         cat $dom > /dev/null
18085         local num=$(get_mdc_stats $mdtidx ost_read)
18086         local ra=$(get_mdc_stats $mdtidx req_active)
18087         local rw=$(get_mdc_stats $mdtidx req_waittime)
18088
18089         [ -z $num ] || error "$num READ RPC occured"
18090         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18091         echo "... DONE"
18092
18093         # compare content
18094         cmp $tmp $dom || error "file miscompare"
18095
18096         return 0
18097 }
18098 run_test 271d "DoM: read on open (1K file in reply buffer)"
18099
18100 test_271f() {
18101         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18102                 skip "Need MDS version at least 2.10.57"
18103
18104         local dom=$DIR/$tdir/dom
18105         local tmp=$TMP/$tfile
18106         trap "cleanup_271def_tests $tmp" EXIT
18107
18108         mkdir -p $DIR/$tdir
18109
18110         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18111
18112         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18113
18114         cancel_lru_locks mdc
18115         dd if=/dev/urandom of=$tmp bs=200000 count=1
18116         dd if=$tmp of=$dom bs=200000 count=1
18117         cancel_lru_locks mdc
18118         cat /etc/hosts >> $tmp
18119         lctl set_param -n mdc.*.stats=clear
18120
18121         echo "Append to the same page"
18122         cat /etc/hosts >> $dom
18123         local num=$(get_mdc_stats $mdtidx ost_read)
18124         local ra=$(get_mdc_stats $mdtidx req_active)
18125         local rw=$(get_mdc_stats $mdtidx req_waittime)
18126
18127         [ -z $num ] || error "$num READ RPC occured"
18128         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18129         echo "... DONE"
18130
18131         # compare content
18132         cmp $tmp $dom || error "file miscompare"
18133
18134         cancel_lru_locks mdc
18135         lctl set_param -n mdc.*.stats=clear
18136
18137         echo "Open and read file"
18138         cat $dom > /dev/null
18139         local num=$(get_mdc_stats $mdtidx ost_read)
18140         local ra=$(get_mdc_stats $mdtidx req_active)
18141         local rw=$(get_mdc_stats $mdtidx req_waittime)
18142
18143         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18144         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18145         echo "... DONE"
18146
18147         # compare content
18148         cmp $tmp $dom || error "file miscompare"
18149
18150         return 0
18151 }
18152 run_test 271f "DoM: read on open (200K file and read tail)"
18153
18154 test_271g() {
18155         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18156                 skip "Skipping due to old client or server version"
18157
18158         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18159         # to get layout
18160         $CHECKSTAT -t file $DIR1/$tfile
18161
18162         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18163         MULTIOP_PID=$!
18164         sleep 1
18165         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18166         $LCTL set_param fail_loc=0x80000314
18167         rm $DIR1/$tfile || error "Unlink fails"
18168         RC=$?
18169         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18170         [ $RC -eq 0 ] || error "Failed write to stale object"
18171 }
18172 run_test 271g "Discard DoM data vs client flush race"
18173
18174 test_272a() {
18175         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18176                 skip "Need MDS version at least 2.11.50"
18177
18178         local dom=$DIR/$tdir/dom
18179         mkdir -p $DIR/$tdir
18180
18181         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18182         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18183                 error "failed to write data into $dom"
18184         local old_md5=$(md5sum $dom)
18185
18186         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18187                 error "failed to migrate to the same DoM component"
18188
18189         local new_md5=$(md5sum $dom)
18190
18191         [ "$old_md5" == "$new_md5" ] ||
18192                 error "md5sum differ: $old_md5, $new_md5"
18193
18194         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18195                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18196 }
18197 run_test 272a "DoM migration: new layout with the same DOM component"
18198
18199 test_272b() {
18200         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18201                 skip "Need MDS version at least 2.11.50"
18202
18203         local dom=$DIR/$tdir/dom
18204         mkdir -p $DIR/$tdir
18205         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18206
18207         local mdtidx=$($LFS getstripe -m $dom)
18208         local mdtname=MDT$(printf %04x $mdtidx)
18209         local facet=mds$((mdtidx + 1))
18210
18211         local mdtfree1=$(do_facet $facet \
18212                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18213         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18214                 error "failed to write data into $dom"
18215         local old_md5=$(md5sum $dom)
18216         cancel_lru_locks mdc
18217         local mdtfree1=$(do_facet $facet \
18218                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18219
18220         $LFS migrate -c2 $dom ||
18221                 error "failed to migrate to the new composite layout"
18222         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18223                 error "MDT stripe was not removed"
18224
18225         cancel_lru_locks mdc
18226         local new_md5=$(md5sum $dom)
18227         [ "$old_md5" != "$new_md5" ] &&
18228                 error "$old_md5 != $new_md5"
18229
18230         # Skip free space checks with ZFS
18231         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18232                 local mdtfree2=$(do_facet $facet \
18233                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18234                 [ $mdtfree2 -gt $mdtfree1 ] ||
18235                         error "MDT space is not freed after migration"
18236         fi
18237         return 0
18238 }
18239 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18240
18241 test_272c() {
18242         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18243                 skip "Need MDS version at least 2.11.50"
18244
18245         local dom=$DIR/$tdir/$tfile
18246         mkdir -p $DIR/$tdir
18247         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18248
18249         local mdtidx=$($LFS getstripe -m $dom)
18250         local mdtname=MDT$(printf %04x $mdtidx)
18251         local facet=mds$((mdtidx + 1))
18252
18253         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18254                 error "failed to write data into $dom"
18255         local old_md5=$(md5sum $dom)
18256         cancel_lru_locks mdc
18257         local mdtfree1=$(do_facet $facet \
18258                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18259
18260         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18261                 error "failed to migrate to the new composite layout"
18262         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18263                 error "MDT stripe was not removed"
18264
18265         cancel_lru_locks mdc
18266         local new_md5=$(md5sum $dom)
18267         [ "$old_md5" != "$new_md5" ] &&
18268                 error "$old_md5 != $new_md5"
18269
18270         # Skip free space checks with ZFS
18271         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18272                 local mdtfree2=$(do_facet $facet \
18273                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18274                 [ $mdtfree2 -gt $mdtfree1 ] ||
18275                         error "MDS space is not freed after migration"
18276         fi
18277         return 0
18278 }
18279 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18280
18281 test_273a() {
18282         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18283                 skip "Need MDS version at least 2.11.50"
18284
18285         # Layout swap cannot be done if either file has DOM component,
18286         # this will never be supported, migration should be used instead
18287
18288         local dom=$DIR/$tdir/$tfile
18289         mkdir -p $DIR/$tdir
18290
18291         $LFS setstripe -c2 ${dom}_plain
18292         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
18293         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
18294                 error "can swap layout with DoM component"
18295         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
18296                 error "can swap layout with DoM component"
18297
18298         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
18299         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
18300                 error "can swap layout with DoM component"
18301         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
18302                 error "can swap layout with DoM component"
18303         return 0
18304 }
18305 run_test 273a "DoM: layout swapping should fail with DOM"
18306
18307 test_275() {
18308         remote_ost_nodsh && skip "remote OST with nodsh"
18309         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
18310                 skip "Need OST version >= 2.10.57"
18311
18312         local file=$DIR/$tfile
18313         local oss
18314
18315         oss=$(comma_list $(osts_nodes))
18316
18317         dd if=/dev/urandom of=$file bs=1M count=2 ||
18318                 error "failed to create a file"
18319         cancel_lru_locks osc
18320
18321         #lock 1
18322         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18323                 error "failed to read a file"
18324
18325 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
18326         $LCTL set_param fail_loc=0x8000031f
18327
18328         cancel_lru_locks osc &
18329         sleep 1
18330
18331 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
18332         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
18333         #IO takes another lock, but matches the PENDING one
18334         #and places it to the IO RPC
18335         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18336                 error "failed to read a file with PENDING lock"
18337 }
18338 run_test 275 "Read on a canceled duplicate lock"
18339
18340 test_276() {
18341         remote_ost_nodsh && skip "remote OST with nodsh"
18342         local pid
18343
18344         do_facet ost1 "(while true; do \
18345                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
18346                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
18347         pid=$!
18348
18349         for LOOP in $(seq 20); do
18350                 stop ost1
18351                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
18352         done
18353         kill -9 $pid
18354         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
18355                 rm $TMP/sanity_276_pid"
18356 }
18357 run_test 276 "Race between mount and obd_statfs"
18358
18359 cleanup_test_300() {
18360         trap 0
18361         umask $SAVE_UMASK
18362 }
18363 test_striped_dir() {
18364         local mdt_index=$1
18365         local stripe_count
18366         local stripe_index
18367
18368         mkdir -p $DIR/$tdir
18369
18370         SAVE_UMASK=$(umask)
18371         trap cleanup_test_300 RETURN EXIT
18372
18373         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
18374                                                 $DIR/$tdir/striped_dir ||
18375                 error "set striped dir error"
18376
18377         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
18378         [ "$mode" = "755" ] || error "expect 755 got $mode"
18379
18380         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
18381                 error "getdirstripe failed"
18382         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
18383         if [ "$stripe_count" != "2" ]; then
18384                 error "1:stripe_count is $stripe_count, expect 2"
18385         fi
18386         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
18387         if [ "$stripe_count" != "2" ]; then
18388                 error "2:stripe_count is $stripe_count, expect 2"
18389         fi
18390
18391         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
18392         if [ "$stripe_index" != "$mdt_index" ]; then
18393                 error "stripe_index is $stripe_index, expect $mdt_index"
18394         fi
18395
18396         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18397                 error "nlink error after create striped dir"
18398
18399         mkdir $DIR/$tdir/striped_dir/a
18400         mkdir $DIR/$tdir/striped_dir/b
18401
18402         stat $DIR/$tdir/striped_dir/a ||
18403                 error "create dir under striped dir failed"
18404         stat $DIR/$tdir/striped_dir/b ||
18405                 error "create dir under striped dir failed"
18406
18407         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
18408                 error "nlink error after mkdir"
18409
18410         rmdir $DIR/$tdir/striped_dir/a
18411         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
18412                 error "nlink error after rmdir"
18413
18414         rmdir $DIR/$tdir/striped_dir/b
18415         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18416                 error "nlink error after rmdir"
18417
18418         chattr +i $DIR/$tdir/striped_dir
18419         createmany -o $DIR/$tdir/striped_dir/f 10 &&
18420                 error "immutable flags not working under striped dir!"
18421         chattr -i $DIR/$tdir/striped_dir
18422
18423         rmdir $DIR/$tdir/striped_dir ||
18424                 error "rmdir striped dir error"
18425
18426         cleanup_test_300
18427
18428         true
18429 }
18430
18431 test_300a() {
18432         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18433                 skip "skipped for lustre < 2.7.0"
18434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18435         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18436
18437         test_striped_dir 0 || error "failed on striped dir on MDT0"
18438         test_striped_dir 1 || error "failed on striped dir on MDT0"
18439 }
18440 run_test 300a "basic striped dir sanity test"
18441
18442 test_300b() {
18443         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18444                 skip "skipped for lustre < 2.7.0"
18445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18446         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18447
18448         local i
18449         local mtime1
18450         local mtime2
18451         local mtime3
18452
18453         test_mkdir $DIR/$tdir || error "mkdir fail"
18454         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18455                 error "set striped dir error"
18456         for i in {0..9}; do
18457                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
18458                 sleep 1
18459                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
18460                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
18461                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
18462                 sleep 1
18463                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
18464                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
18465                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
18466         done
18467         true
18468 }
18469 run_test 300b "check ctime/mtime for striped dir"
18470
18471 test_300c() {
18472         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18473                 skip "skipped for lustre < 2.7.0"
18474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18475         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18476
18477         local file_count
18478
18479         mkdir -p $DIR/$tdir
18480         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
18481                 error "set striped dir error"
18482
18483         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
18484                 error "chown striped dir failed"
18485
18486         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
18487                 error "create 5k files failed"
18488
18489         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
18490
18491         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
18492
18493         rm -rf $DIR/$tdir
18494 }
18495 run_test 300c "chown && check ls under striped directory"
18496
18497 test_300d() {
18498         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18499                 skip "skipped for lustre < 2.7.0"
18500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18501         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18502
18503         local stripe_count
18504         local file
18505
18506         mkdir -p $DIR/$tdir
18507         $LFS setstripe -c 2 $DIR/$tdir
18508
18509         #local striped directory
18510         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18511                 error "set striped dir error"
18512         createmany -o $DIR/$tdir/striped_dir/f 10 ||
18513                 error "create 10 files failed"
18514
18515         #remote striped directory
18516         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
18517                 error "set striped dir error"
18518         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
18519                 error "create 10 files failed"
18520
18521         for file in $(find $DIR/$tdir); do
18522                 stripe_count=$($LFS getstripe -c $file)
18523                 [ $stripe_count -eq 2 ] ||
18524                         error "wrong stripe $stripe_count for $file"
18525         done
18526
18527         rm -rf $DIR/$tdir
18528 }
18529 run_test 300d "check default stripe under striped directory"
18530
18531 test_300e() {
18532         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18533                 skip "Need MDS version at least 2.7.55"
18534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18535         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18536
18537         local stripe_count
18538         local file
18539
18540         mkdir -p $DIR/$tdir
18541
18542         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18543                 error "set striped dir error"
18544
18545         touch $DIR/$tdir/striped_dir/a
18546         touch $DIR/$tdir/striped_dir/b
18547         touch $DIR/$tdir/striped_dir/c
18548
18549         mkdir $DIR/$tdir/striped_dir/dir_a
18550         mkdir $DIR/$tdir/striped_dir/dir_b
18551         mkdir $DIR/$tdir/striped_dir/dir_c
18552
18553         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18554                 error "set striped adir under striped dir error"
18555
18556         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18557                 error "set striped bdir under striped dir error"
18558
18559         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18560                 error "set striped cdir under striped dir error"
18561
18562         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18563                 error "rename dir under striped dir fails"
18564
18565         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18566                 error "rename dir under different stripes fails"
18567
18568         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18569                 error "rename file under striped dir should succeed"
18570
18571         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18572                 error "rename dir under striped dir should succeed"
18573
18574         rm -rf $DIR/$tdir
18575 }
18576 run_test 300e "check rename under striped directory"
18577
18578 test_300f() {
18579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18580         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18581         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18582                 skip "Need MDS version at least 2.7.55"
18583
18584         local stripe_count
18585         local file
18586
18587         rm -rf $DIR/$tdir
18588         mkdir -p $DIR/$tdir
18589
18590         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18591                 error "set striped dir error"
18592
18593         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18594                 error "set striped dir error"
18595
18596         touch $DIR/$tdir/striped_dir/a
18597         mkdir $DIR/$tdir/striped_dir/dir_a
18598         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18599                 error "create striped dir under striped dir fails"
18600
18601         touch $DIR/$tdir/striped_dir1/b
18602         mkdir $DIR/$tdir/striped_dir1/dir_b
18603         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18604                 error "create striped dir under striped dir fails"
18605
18606         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18607                 error "rename dir under different striped dir should fail"
18608
18609         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18610                 error "rename striped dir under diff striped dir should fail"
18611
18612         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18613                 error "rename file under diff striped dirs fails"
18614
18615         rm -rf $DIR/$tdir
18616 }
18617 run_test 300f "check rename cross striped directory"
18618
18619 test_300_check_default_striped_dir()
18620 {
18621         local dirname=$1
18622         local default_count=$2
18623         local default_index=$3
18624         local stripe_count
18625         local stripe_index
18626         local dir_stripe_index
18627         local dir
18628
18629         echo "checking $dirname $default_count $default_index"
18630         $LFS setdirstripe -D -c $default_count -i $default_index \
18631                                 -t all_char $DIR/$tdir/$dirname ||
18632                 error "set default stripe on striped dir error"
18633         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18634         [ $stripe_count -eq $default_count ] ||
18635                 error "expect $default_count get $stripe_count for $dirname"
18636
18637         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18638         [ $stripe_index -eq $default_index ] ||
18639                 error "expect $default_index get $stripe_index for $dirname"
18640
18641         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18642                                                 error "create dirs failed"
18643
18644         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18645         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18646         for dir in $(find $DIR/$tdir/$dirname/*); do
18647                 stripe_count=$($LFS getdirstripe -c $dir)
18648                 [ $stripe_count -eq $default_count ] ||
18649                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18650                 error "stripe count $default_count != $stripe_count for $dir"
18651
18652                 stripe_index=$($LFS getdirstripe -i $dir)
18653                 [ $default_index -eq -1 ] ||
18654                         [ $stripe_index -eq $default_index ] ||
18655                         error "$stripe_index != $default_index for $dir"
18656
18657                 #check default stripe
18658                 stripe_count=$($LFS getdirstripe -D -c $dir)
18659                 [ $stripe_count -eq $default_count ] ||
18660                 error "default count $default_count != $stripe_count for $dir"
18661
18662                 stripe_index=$($LFS getdirstripe -D -i $dir)
18663                 [ $stripe_index -eq $default_index ] ||
18664                 error "default index $default_index != $stripe_index for $dir"
18665         done
18666         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18667 }
18668
18669 test_300g() {
18670         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18671         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18672                 skip "Need MDS version at least 2.7.55"
18673
18674         local dir
18675         local stripe_count
18676         local stripe_index
18677
18678         mkdir $DIR/$tdir
18679         mkdir $DIR/$tdir/normal_dir
18680
18681         #Checking when client cache stripe index
18682         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18683         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18684                 error "create striped_dir failed"
18685
18686         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18687                 error "create dir0 fails"
18688         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18689         [ $stripe_index -eq 0 ] ||
18690                 error "dir0 expect index 0 got $stripe_index"
18691
18692         mkdir $DIR/$tdir/striped_dir/dir1 ||
18693                 error "create dir1 fails"
18694         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18695         [ $stripe_index -eq 1 ] ||
18696                 error "dir1 expect index 1 got $stripe_index"
18697
18698         #check default stripe count/stripe index
18699         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18700         test_300_check_default_striped_dir normal_dir 1 0
18701         test_300_check_default_striped_dir normal_dir 2 1
18702         test_300_check_default_striped_dir normal_dir 2 -1
18703
18704         #delete default stripe information
18705         echo "delete default stripeEA"
18706         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18707                 error "set default stripe on striped dir error"
18708
18709         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18710         for dir in $(find $DIR/$tdir/normal_dir/*); do
18711                 stripe_count=$($LFS getdirstripe -c $dir)
18712                 [ $stripe_count -eq 0 ] ||
18713                         error "expect 1 get $stripe_count for $dir"
18714                 stripe_index=$($LFS getdirstripe -i $dir)
18715                 [ $stripe_index -eq 0 ] ||
18716                         error "expect 0 get $stripe_index for $dir"
18717         done
18718 }
18719 run_test 300g "check default striped directory for normal directory"
18720
18721 test_300h() {
18722         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18723         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18724                 skip "Need MDS version at least 2.7.55"
18725
18726         local dir
18727         local stripe_count
18728
18729         mkdir $DIR/$tdir
18730         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18731                 error "set striped dir error"
18732
18733         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18734         test_300_check_default_striped_dir striped_dir 1 0
18735         test_300_check_default_striped_dir striped_dir 2 1
18736         test_300_check_default_striped_dir striped_dir 2 -1
18737
18738         #delete default stripe information
18739         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18740                 error "set default stripe on striped dir error"
18741
18742         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18743         for dir in $(find $DIR/$tdir/striped_dir/*); do
18744                 stripe_count=$($LFS getdirstripe -c $dir)
18745                 [ $stripe_count -eq 0 ] ||
18746                         error "expect 1 get $stripe_count for $dir"
18747         done
18748 }
18749 run_test 300h "check default striped directory for striped directory"
18750
18751 test_300i() {
18752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18754         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18755                 skip "Need MDS version at least 2.7.55"
18756
18757         local stripe_count
18758         local file
18759
18760         mkdir $DIR/$tdir
18761
18762         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18763                 error "set striped dir error"
18764
18765         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18766                 error "create files under striped dir failed"
18767
18768         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18769                 error "set striped hashdir error"
18770
18771         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18772                 error "create dir0 under hash dir failed"
18773         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18774                 error "create dir1 under hash dir failed"
18775
18776         # unfortunately, we need to umount to clear dir layout cache for now
18777         # once we fully implement dir layout, we can drop this
18778         umount_client $MOUNT || error "umount failed"
18779         mount_client $MOUNT || error "mount failed"
18780
18781         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18782         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18783         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18784
18785         #set the stripe to be unknown hash type
18786         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18787         $LCTL set_param fail_loc=0x1901
18788         for ((i = 0; i < 10; i++)); do
18789                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18790                         error "stat f-$i failed"
18791                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18792         done
18793
18794         touch $DIR/$tdir/striped_dir/f0 &&
18795                 error "create under striped dir with unknown hash should fail"
18796
18797         $LCTL set_param fail_loc=0
18798
18799         umount_client $MOUNT || error "umount failed"
18800         mount_client $MOUNT || error "mount failed"
18801
18802         return 0
18803 }
18804 run_test 300i "client handle unknown hash type striped directory"
18805
18806 test_300j() {
18807         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18809         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18810                 skip "Need MDS version at least 2.7.55"
18811
18812         local stripe_count
18813         local file
18814
18815         mkdir $DIR/$tdir
18816
18817         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18818         $LCTL set_param fail_loc=0x1702
18819         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18820                 error "set striped dir error"
18821
18822         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18823                 error "create files under striped dir failed"
18824
18825         $LCTL set_param fail_loc=0
18826
18827         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18828
18829         return 0
18830 }
18831 run_test 300j "test large update record"
18832
18833 test_300k() {
18834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18835         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18836         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18837                 skip "Need MDS version at least 2.7.55"
18838
18839         # this test needs a huge transaction
18840         local kb
18841         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18842         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18843
18844         local stripe_count
18845         local file
18846
18847         mkdir $DIR/$tdir
18848
18849         #define OBD_FAIL_LARGE_STRIPE   0x1703
18850         $LCTL set_param fail_loc=0x1703
18851         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18852                 error "set striped dir error"
18853         $LCTL set_param fail_loc=0
18854
18855         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18856                 error "getstripeddir fails"
18857         rm -rf $DIR/$tdir/striped_dir ||
18858                 error "unlink striped dir fails"
18859
18860         return 0
18861 }
18862 run_test 300k "test large striped directory"
18863
18864 test_300l() {
18865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18866         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18867         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18868                 skip "Need MDS version at least 2.7.55"
18869
18870         local stripe_index
18871
18872         test_mkdir -p $DIR/$tdir/striped_dir
18873         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18874                         error "chown $RUNAS_ID failed"
18875         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18876                 error "set default striped dir failed"
18877
18878         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18879         $LCTL set_param fail_loc=0x80000158
18880         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18881
18882         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18883         [ $stripe_index -eq 1 ] ||
18884                 error "expect 1 get $stripe_index for $dir"
18885 }
18886 run_test 300l "non-root user to create dir under striped dir with stale layout"
18887
18888 test_300m() {
18889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18890         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18891         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18892                 skip "Need MDS version at least 2.7.55"
18893
18894         mkdir -p $DIR/$tdir/striped_dir
18895         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18896                 error "set default stripes dir error"
18897
18898         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18899
18900         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18901         [ $stripe_count -eq 0 ] ||
18902                         error "expect 0 get $stripe_count for a"
18903
18904         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18905                 error "set default stripes dir error"
18906
18907         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18908
18909         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18910         [ $stripe_count -eq 0 ] ||
18911                         error "expect 0 get $stripe_count for b"
18912
18913         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18914                 error "set default stripes dir error"
18915
18916         mkdir $DIR/$tdir/striped_dir/c &&
18917                 error "default stripe_index is invalid, mkdir c should fails"
18918
18919         rm -rf $DIR/$tdir || error "rmdir fails"
18920 }
18921 run_test 300m "setstriped directory on single MDT FS"
18922
18923 cleanup_300n() {
18924         local list=$(comma_list $(mdts_nodes))
18925
18926         trap 0
18927         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18928 }
18929
18930 test_300n() {
18931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18932         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18933         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18934                 skip "Need MDS version at least 2.7.55"
18935         remote_mds_nodsh && skip "remote MDS with nodsh"
18936
18937         local stripe_index
18938         local list=$(comma_list $(mdts_nodes))
18939
18940         trap cleanup_300n RETURN EXIT
18941         mkdir -p $DIR/$tdir
18942         chmod 777 $DIR/$tdir
18943         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18944                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18945                 error "create striped dir succeeds with gid=0"
18946
18947         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18948         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18949                 error "create striped dir fails with gid=-1"
18950
18951         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18952         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18953                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18954                 error "set default striped dir succeeds with gid=0"
18955
18956
18957         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18958         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18959                 error "set default striped dir fails with gid=-1"
18960
18961
18962         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18963         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18964                                         error "create test_dir fails"
18965         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18966                                         error "create test_dir1 fails"
18967         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18968                                         error "create test_dir2 fails"
18969         cleanup_300n
18970 }
18971 run_test 300n "non-root user to create dir under striped dir with default EA"
18972
18973 test_300o() {
18974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18975         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18976         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18977                 skip "Need MDS version at least 2.7.55"
18978
18979         local numfree1
18980         local numfree2
18981
18982         mkdir -p $DIR/$tdir
18983
18984         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18985         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18986         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
18987                 skip "not enough free inodes $numfree1 $numfree2"
18988         fi
18989
18990         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18991         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18992         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
18993                 skip "not enough free space $numfree1 $numfree2"
18994         fi
18995
18996         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18997                 error "setdirstripe fails"
18998
18999         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
19000                 error "create dirs fails"
19001
19002         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
19003         ls $DIR/$tdir/striped_dir > /dev/null ||
19004                 error "ls striped dir fails"
19005         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
19006                 error "unlink big striped dir fails"
19007 }
19008 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
19009
19010 test_300p() {
19011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19012         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19013         remote_mds_nodsh && skip "remote MDS with nodsh"
19014
19015         mkdir -p $DIR/$tdir
19016
19017         #define OBD_FAIL_OUT_ENOSPC     0x1704
19018         do_facet mds2 lctl set_param fail_loc=0x80001704
19019         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
19020                  && error "create striped directory should fail"
19021
19022         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
19023
19024         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
19025         true
19026 }
19027 run_test 300p "create striped directory without space"
19028
19029 test_300q() {
19030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19031         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19032
19033         local fd=$(free_fd)
19034         local cmd="exec $fd<$tdir"
19035         cd $DIR
19036         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
19037         eval $cmd
19038         cmd="exec $fd<&-"
19039         trap "eval $cmd" EXIT
19040         cd $tdir || error "cd $tdir fails"
19041         rmdir  ../$tdir || error "rmdir $tdir fails"
19042         mkdir local_dir && error "create dir succeeds"
19043         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
19044         eval $cmd
19045         return 0
19046 }
19047 run_test 300q "create remote directory under orphan directory"
19048
19049 test_300r() {
19050         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
19051                 skip "Need MDS version at least 2.7.55" && return
19052         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19053
19054         mkdir $DIR/$tdir
19055
19056         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19057                 error "set striped dir error"
19058
19059         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19060                 error "getstripeddir fails"
19061
19062         local stripe_count
19063         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19064                       awk '/lmv_stripe_count:/ { print $2 }')
19065
19066         [ $MDSCOUNT -ne $stripe_count ] &&
19067                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19068
19069         rm -rf $DIR/$tdir/striped_dir ||
19070                 error "unlink striped dir fails"
19071 }
19072 run_test 300r "test -1 striped directory"
19073
19074 prepare_remote_file() {
19075         mkdir $DIR/$tdir/src_dir ||
19076                 error "create remote source failed"
19077
19078         cp /etc/hosts $DIR/$tdir/src_dir/a ||
19079                  error "cp to remote source failed"
19080         touch $DIR/$tdir/src_dir/a
19081
19082         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
19083                 error "create remote target dir failed"
19084
19085         touch $DIR/$tdir/tgt_dir/b
19086
19087         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
19088                 error "rename dir cross MDT failed!"
19089
19090         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
19091                 error "src_child still exists after rename"
19092
19093         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
19094                 error "missing file(a) after rename"
19095
19096         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
19097                 error "diff after rename"
19098 }
19099
19100 test_310a() {
19101         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19103
19104         local remote_file=$DIR/$tdir/tgt_dir/b
19105
19106         mkdir -p $DIR/$tdir
19107
19108         prepare_remote_file || error "prepare remote file failed"
19109
19110         #open-unlink file
19111         $OPENUNLINK $remote_file $remote_file ||
19112                 error "openunlink $remote_file failed"
19113         $CHECKSTAT -a $remote_file || error "$remote_file exists"
19114 }
19115 run_test 310a "open unlink remote file"
19116
19117 test_310b() {
19118         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19120
19121         local remote_file=$DIR/$tdir/tgt_dir/b
19122
19123         mkdir -p $DIR/$tdir
19124
19125         prepare_remote_file || error "prepare remote file failed"
19126
19127         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19128         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19129         $CHECKSTAT -t file $remote_file || error "check file failed"
19130 }
19131 run_test 310b "unlink remote file with multiple links while open"
19132
19133 test_310c() {
19134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19135         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19136
19137         local remote_file=$DIR/$tdir/tgt_dir/b
19138
19139         mkdir -p $DIR/$tdir
19140
19141         prepare_remote_file || error "prepare remote file failed"
19142
19143         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19144         multiop_bg_pause $remote_file O_uc ||
19145                         error "mulitop failed for remote file"
19146         MULTIPID=$!
19147         $MULTIOP $DIR/$tfile Ouc
19148         kill -USR1 $MULTIPID
19149         wait $MULTIPID
19150 }
19151 run_test 310c "open-unlink remote file with multiple links"
19152
19153 #LU-4825
19154 test_311() {
19155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19156         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19157         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
19158                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
19159         remote_mds_nodsh && skip "remote MDS with nodsh"
19160
19161         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19162         local mdts=$(comma_list $(mdts_nodes))
19163
19164         mkdir -p $DIR/$tdir
19165         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19166         createmany -o $DIR/$tdir/$tfile. 1000
19167
19168         # statfs data is not real time, let's just calculate it
19169         old_iused=$((old_iused + 1000))
19170
19171         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19172                         osp.*OST0000*MDT0000.create_count")
19173         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19174                                 osp.*OST0000*MDT0000.max_create_count")
19175         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
19176
19177         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
19178         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
19179         [ $index -ne 0 ] || error "$tfile stripe index is 0"
19180
19181         unlinkmany $DIR/$tdir/$tfile. 1000
19182
19183         do_nodes $mdts "$LCTL set_param -n \
19184                         osp.*OST0000*.max_create_count=$max_count"
19185         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
19186                 do_nodes $mdts "$LCTL set_param -n \
19187                                 osp.*OST0000*.create_count=$count"
19188         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
19189                         grep "=0" && error "create_count is zero"
19190
19191         local new_iused
19192         for i in $(seq 120); do
19193                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19194                 # system may be too busy to destroy all objs in time, use
19195                 # a somewhat small value to not fail autotest
19196                 [ $((old_iused - new_iused)) -gt 400 ] && break
19197                 sleep 1
19198         done
19199
19200         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
19201         [ $((old_iused - new_iused)) -gt 400 ] ||
19202                 error "objs not destroyed after unlink"
19203 }
19204 run_test 311 "disable OSP precreate, and unlink should destroy objs"
19205
19206 zfs_oid_to_objid()
19207 {
19208         local ost=$1
19209         local objid=$2
19210
19211         local vdevdir=$(dirname $(facet_vdevice $ost))
19212         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
19213         local zfs_zapid=$(do_facet $ost $cmd |
19214                           grep -w "/O/0/d$((objid%32))" -C 5 |
19215                           awk '/Object/{getline; print $1}')
19216         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
19217                           awk "/$objid = /"'{printf $3}')
19218
19219         echo $zfs_objid
19220 }
19221
19222 zfs_object_blksz() {
19223         local ost=$1
19224         local objid=$2
19225
19226         local vdevdir=$(dirname $(facet_vdevice $ost))
19227         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
19228         local blksz=$(do_facet $ost $cmd $objid |
19229                       awk '/dblk/{getline; printf $4}')
19230
19231         case "${blksz: -1}" in
19232                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
19233                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
19234                 *) ;;
19235         esac
19236
19237         echo $blksz
19238 }
19239
19240 test_312() { # LU-4856
19241         remote_ost_nodsh && skip "remote OST with nodsh"
19242         [ "$ost1_FSTYPE" = "zfs" ] ||
19243                 skip_env "the test only applies to zfs"
19244
19245         local max_blksz=$(do_facet ost1 \
19246                           $ZFS get -p recordsize $(facet_device ost1) |
19247                           awk '!/VALUE/{print $3}')
19248
19249         # to make life a little bit easier
19250         $LFS mkdir -c 1 -i 0 $DIR/$tdir
19251         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19252
19253         local tf=$DIR/$tdir/$tfile
19254         touch $tf
19255         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19256
19257         # Get ZFS object id
19258         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19259         # block size change by sequential overwrite
19260         local bs
19261
19262         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
19263                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
19264
19265                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
19266                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
19267         done
19268         rm -f $tf
19269
19270         # block size change by sequential append write
19271         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
19272         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19273         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19274         local count
19275
19276         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
19277                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
19278                         oflag=sync conv=notrunc
19279
19280                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
19281                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
19282                         error "blksz error, actual $blksz, " \
19283                                 "expected: 2 * $count * $PAGE_SIZE"
19284         done
19285         rm -f $tf
19286
19287         # random write
19288         touch $tf
19289         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19290         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19291
19292         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
19293         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19294         [ $blksz -eq $PAGE_SIZE ] ||
19295                 error "blksz error: $blksz, expected: $PAGE_SIZE"
19296
19297         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
19298         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19299         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
19300
19301         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
19302         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19303         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
19304 }
19305 run_test 312 "make sure ZFS adjusts its block size by write pattern"
19306
19307 test_313() {
19308         remote_ost_nodsh && skip "remote OST with nodsh"
19309
19310         local file=$DIR/$tfile
19311
19312         rm -f $file
19313         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
19314
19315         # define OBD_FAIL_TGT_RCVD_EIO           0x720
19316         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19317         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
19318                 error "write should failed"
19319         do_facet ost1 "$LCTL set_param fail_loc=0"
19320         rm -f $file
19321 }
19322 run_test 313 "io should fail after last_rcvd update fail"
19323
19324 test_314() {
19325         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19326
19327         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
19328         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19329         rm -f $DIR/$tfile
19330         wait_delete_completed
19331         do_facet ost1 "$LCTL set_param fail_loc=0"
19332 }
19333 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
19334
19335 test_315() { # LU-618
19336         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
19337
19338         local file=$DIR/$tfile
19339         rm -f $file
19340
19341         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
19342                 error "multiop file write failed"
19343         $MULTIOP $file oO_RDONLY:r4063232_c &
19344         PID=$!
19345
19346         sleep 2
19347
19348         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
19349         kill -USR1 $PID
19350
19351         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
19352         rm -f $file
19353 }
19354 run_test 315 "read should be accounted"
19355
19356 test_316() {
19357         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19358         large_xattr_enabled || skip_env "ea_inode feature disabled"
19359
19360         rm -rf $DIR/$tdir/d
19361         mkdir -p $DIR/$tdir/d
19362         chown nobody $DIR/$tdir/d
19363         touch $DIR/$tdir/d/file
19364
19365         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
19366 }
19367 run_test 316 "lfs mv"
19368
19369 test_317() {
19370         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
19371                 skip "Need MDS version at least 2.11.53"
19372         local trunc_sz
19373         local grant_blk_size
19374
19375         if [ "$(facet_fstype $facet)" == "zfs" ]; then
19376                 skip "LU-10370: no implementation for ZFS" && return
19377         fi
19378
19379         stack_trap "rm -f $DIR/$tfile" EXIT
19380         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
19381                         awk '/grant_block_size:/ { print $2; exit; }')
19382         #
19383         # Create File of size 5M. Truncate it to below size's and verify
19384         # blocks count.
19385         #
19386         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
19387                 error "Create file : $DIR/$tfile"
19388
19389         for trunc_sz in 2097152 4097 4000 509 0; do
19390                 $TRUNCATE $DIR/$tfile $trunc_sz ||
19391                         error "truncate $tfile to $trunc_sz failed"
19392                 local sz=$(stat --format=%s $DIR/$tfile)
19393                 local blk=$(stat --format=%b $DIR/$tfile)
19394                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
19395                                      grant_blk_size) * 8))
19396
19397                 if [[ $blk -ne $trunc_blk ]]; then
19398                         $(which stat) $DIR/$tfile
19399                         error "Expected Block $trunc_blk got $blk for $tfile"
19400                 fi
19401
19402                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19403                         error "Expected Size $trunc_sz got $sz for $tfile"
19404         done
19405
19406         #
19407         # sparse file test
19408         # Create file with a hole and write actual two blocks. Block count
19409         # must be 16.
19410         #
19411         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
19412                 conv=fsync || error "Create file : $DIR/$tfile"
19413
19414         # Calculate the final truncate size.
19415         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
19416
19417         #
19418         # truncate to size $trunc_sz bytes. Strip the last block
19419         # The block count must drop to 8
19420         #
19421         $TRUNCATE $DIR/$tfile $trunc_sz ||
19422                 error "truncate $tfile to $trunc_sz failed"
19423
19424         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
19425         sz=$(stat --format=%s $DIR/$tfile)
19426         blk=$(stat --format=%b $DIR/$tfile)
19427
19428         if [[ $blk -ne $trunc_bsz ]]; then
19429                 $(which stat) $DIR/$tfile
19430                 error "Expected Block $trunc_bsz got $blk for $tfile"
19431         fi
19432
19433         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19434                 error "Expected Size $trunc_sz got $sz for $tfile"
19435 }
19436 run_test 317 "Verify blocks get correctly update after truncate"
19437
19438 test_318() {
19439         local old_max_active=$($LCTL get_param -n \
19440                             llite.*.max_read_ahead_async_active 2>/dev/null)
19441
19442         $LCTL set_param llite.*.max_read_ahead_async_active=256
19443         local max_active=$($LCTL get_param -n \
19444                            llite.*.max_read_ahead_async_active 2>/dev/null)
19445         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
19446
19447         # currently reset to 0 is unsupported, leave it 512 for now.
19448         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
19449                 error "set max_read_ahead_async_active should fail"
19450
19451         $LCTL set_param llite.*.max_read_ahead_async_active=512
19452         max_active=$($LCTL get_param -n \
19453                      llite.*.max_read_ahead_async_active 2>/dev/null)
19454         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
19455
19456         # restore @max_active
19457         [ $old_max_active -ne 0 ] && $LCTL set_param \
19458                 llite.*.max_read_ahead_async_active=$old_max_active
19459
19460         local old_threshold=$($LCTL get_param -n \
19461                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19462         local max_per_file_mb=$($LCTL get_param -n \
19463                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
19464
19465         local invalid=$(($max_per_file_mb + 1))
19466         $LCTL set_param \
19467                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
19468                         && error "set $invalid should fail"
19469
19470         local valid=$(($invalid - 1))
19471         $LCTL set_param \
19472                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
19473                         error "set $valid should succeed"
19474         local threshold=$($LCTL get_param -n \
19475                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19476         [ $threshold -eq $valid ] || error \
19477                 "expect threshold $valid got $threshold"
19478         $LCTL set_param \
19479                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
19480 }
19481 run_test 318 "Verify async readahead tunables"
19482
19483 test_319() {
19484         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
19485
19486         local before=$(date +%s)
19487         local evict
19488         local mdir=$DIR/$tdir
19489         local file=$mdir/xxx
19490
19491         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
19492         touch $file
19493
19494 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
19495         $LCTL set_param fail_val=5 fail_loc=0x8000032c
19496         $LFS mv -m1 $file &
19497
19498         sleep 1
19499         dd if=$file of=/dev/null
19500         wait
19501         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
19502           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
19503
19504         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
19505 }
19506 run_test 319 "lost lease lock on migrate error"
19507
19508 test_fake_rw() {
19509         local read_write=$1
19510         if [ "$read_write" = "write" ]; then
19511                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
19512         elif [ "$read_write" = "read" ]; then
19513                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
19514         else
19515                 error "argument error"
19516         fi
19517
19518         # turn off debug for performance testing
19519         local saved_debug=$($LCTL get_param -n debug)
19520         $LCTL set_param debug=0
19521
19522         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19523
19524         # get ost1 size - lustre-OST0000
19525         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
19526         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
19527         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
19528
19529         if [ "$read_write" = "read" ]; then
19530                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
19531         fi
19532
19533         local start_time=$(date +%s.%N)
19534         $dd_cmd bs=1M count=$blocks oflag=sync ||
19535                 error "real dd $read_write error"
19536         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
19537
19538         if [ "$read_write" = "write" ]; then
19539                 rm -f $DIR/$tfile
19540         fi
19541
19542         # define OBD_FAIL_OST_FAKE_RW           0x238
19543         do_facet ost1 $LCTL set_param fail_loc=0x238
19544
19545         local start_time=$(date +%s.%N)
19546         $dd_cmd bs=1M count=$blocks oflag=sync ||
19547                 error "fake dd $read_write error"
19548         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
19549
19550         if [ "$read_write" = "write" ]; then
19551                 # verify file size
19552                 cancel_lru_locks osc
19553                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
19554                         error "$tfile size not $blocks MB"
19555         fi
19556         do_facet ost1 $LCTL set_param fail_loc=0
19557
19558         echo "fake $read_write $duration_fake vs. normal $read_write" \
19559                 "$duration in seconds"
19560         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
19561                 error_not_in_vm "fake write is slower"
19562
19563         $LCTL set_param -n debug="$saved_debug"
19564         rm -f $DIR/$tfile
19565 }
19566 test_399a() { # LU-7655 for OST fake write
19567         remote_ost_nodsh && skip "remote OST with nodsh"
19568
19569         test_fake_rw write
19570 }
19571 run_test 399a "fake write should not be slower than normal write"
19572
19573 test_399b() { # LU-8726 for OST fake read
19574         remote_ost_nodsh && skip "remote OST with nodsh"
19575         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
19576                 skip_env "ldiskfs only test"
19577         fi
19578
19579         test_fake_rw read
19580 }
19581 run_test 399b "fake read should not be slower than normal read"
19582
19583 test_400a() { # LU-1606, was conf-sanity test_74
19584         if ! which $CC > /dev/null 2>&1; then
19585                 skip_env "$CC is not installed"
19586         fi
19587
19588         local extra_flags=''
19589         local out=$TMP/$tfile
19590         local prefix=/usr/include/lustre
19591         local prog
19592
19593         if ! [[ -d $prefix ]]; then
19594                 # Assume we're running in tree and fixup the include path.
19595                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19596                 extra_flags+=" -L$LUSTRE/utils/.lib"
19597         fi
19598
19599         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19600                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19601                         error "client api broken"
19602         done
19603         rm -f $out
19604 }
19605 run_test 400a "Lustre client api program can compile and link"
19606
19607 test_400b() { # LU-1606, LU-5011
19608         local header
19609         local out=$TMP/$tfile
19610         local prefix=/usr/include/linux/lustre
19611
19612         # We use a hard coded prefix so that this test will not fail
19613         # when run in tree. There are headers in lustre/include/lustre/
19614         # that are not packaged (like lustre_idl.h) and have more
19615         # complicated include dependencies (like config.h and lnet/types.h).
19616         # Since this test about correct packaging we just skip them when
19617         # they don't exist (see below) rather than try to fixup cppflags.
19618
19619         if ! which $CC > /dev/null 2>&1; then
19620                 skip_env "$CC is not installed"
19621         fi
19622
19623         for header in $prefix/*.h; do
19624                 if ! [[ -f "$header" ]]; then
19625                         continue
19626                 fi
19627
19628                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19629                         continue # lustre_ioctl.h is internal header
19630                 fi
19631
19632                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19633                         error "cannot compile '$header'"
19634         done
19635         rm -f $out
19636 }
19637 run_test 400b "packaged headers can be compiled"
19638
19639 test_401a() { #LU-7437
19640         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19641         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19642
19643         #count the number of parameters by "list_param -R"
19644         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19645         #count the number of parameters by listing proc files
19646         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19647         echo "proc_dirs='$proc_dirs'"
19648         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19649         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19650                       sort -u | wc -l)
19651
19652         [ $params -eq $procs ] ||
19653                 error "found $params parameters vs. $procs proc files"
19654
19655         # test the list_param -D option only returns directories
19656         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19657         #count the number of parameters by listing proc directories
19658         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19659                 sort -u | wc -l)
19660
19661         [ $params -eq $procs ] ||
19662                 error "found $params parameters vs. $procs proc files"
19663 }
19664 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19665
19666 test_401b() {
19667         local save=$($LCTL get_param -n jobid_var)
19668         local tmp=testing
19669
19670         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19671                 error "no error returned when setting bad parameters"
19672
19673         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19674         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19675
19676         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19677         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19678         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19679 }
19680 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19681
19682 test_401c() {
19683         local jobid_var_old=$($LCTL get_param -n jobid_var)
19684         local jobid_var_new
19685
19686         $LCTL set_param jobid_var= &&
19687                 error "no error returned for 'set_param a='"
19688
19689         jobid_var_new=$($LCTL get_param -n jobid_var)
19690         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19691                 error "jobid_var was changed by setting without value"
19692
19693         $LCTL set_param jobid_var &&
19694                 error "no error returned for 'set_param a'"
19695
19696         jobid_var_new=$($LCTL get_param -n jobid_var)
19697         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19698                 error "jobid_var was changed by setting without value"
19699 }
19700 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19701
19702 test_401d() {
19703         local jobid_var_old=$($LCTL get_param -n jobid_var)
19704         local jobid_var_new
19705         local new_value="foo=bar"
19706
19707         $LCTL set_param jobid_var=$new_value ||
19708                 error "'set_param a=b' did not accept a value containing '='"
19709
19710         jobid_var_new=$($LCTL get_param -n jobid_var)
19711         [[ "$jobid_var_new" == "$new_value" ]] ||
19712                 error "'set_param a=b' failed on a value containing '='"
19713
19714         # Reset the jobid_var to test the other format
19715         $LCTL set_param jobid_var=$jobid_var_old
19716         jobid_var_new=$($LCTL get_param -n jobid_var)
19717         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19718                 error "failed to reset jobid_var"
19719
19720         $LCTL set_param jobid_var $new_value ||
19721                 error "'set_param a b' did not accept a value containing '='"
19722
19723         jobid_var_new=$($LCTL get_param -n jobid_var)
19724         [[ "$jobid_var_new" == "$new_value" ]] ||
19725                 error "'set_param a b' failed on a value containing '='"
19726
19727         $LCTL set_param jobid_var $jobid_var_old
19728         jobid_var_new=$($LCTL get_param -n jobid_var)
19729         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19730                 error "failed to reset jobid_var"
19731 }
19732 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19733
19734 test_402() {
19735         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19736         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19737                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19738         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19739                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19740                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19741         remote_mds_nodsh && skip "remote MDS with nodsh"
19742
19743         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19744 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19745         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19746         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19747                 echo "Touch failed - OK"
19748 }
19749 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19750
19751 test_403() {
19752         local file1=$DIR/$tfile.1
19753         local file2=$DIR/$tfile.2
19754         local tfile=$TMP/$tfile
19755
19756         rm -f $file1 $file2 $tfile
19757
19758         touch $file1
19759         ln $file1 $file2
19760
19761         # 30 sec OBD_TIMEOUT in ll_getattr()
19762         # right before populating st_nlink
19763         $LCTL set_param fail_loc=0x80001409
19764         stat -c %h $file1 > $tfile &
19765
19766         # create an alias, drop all locks and reclaim the dentry
19767         < $file2
19768         cancel_lru_locks mdc
19769         cancel_lru_locks osc
19770         sysctl -w vm.drop_caches=2
19771
19772         wait
19773
19774         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19775
19776         rm -f $tfile $file1 $file2
19777 }
19778 run_test 403 "i_nlink should not drop to zero due to aliasing"
19779
19780 test_404() { # LU-6601
19781         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19782                 skip "Need server version newer than 2.8.52"
19783         remote_mds_nodsh && skip "remote MDS with nodsh"
19784
19785         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19786                 awk '/osp .*-osc-MDT/ { print $4}')
19787
19788         local osp
19789         for osp in $mosps; do
19790                 echo "Deactivate: " $osp
19791                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19792                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19793                         awk -vp=$osp '$4 == p { print $2 }')
19794                 [ $stat = IN ] || {
19795                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19796                         error "deactivate error"
19797                 }
19798                 echo "Activate: " $osp
19799                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19800                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19801                         awk -vp=$osp '$4 == p { print $2 }')
19802                 [ $stat = UP ] || {
19803                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19804                         error "activate error"
19805                 }
19806         done
19807 }
19808 run_test 404 "validate manual {de}activated works properly for OSPs"
19809
19810 test_405() {
19811         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19812         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19813                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19814                         skip "Layout swap lock is not supported"
19815
19816         check_swap_layouts_support
19817
19818         test_mkdir $DIR/$tdir
19819         swap_lock_test -d $DIR/$tdir ||
19820                 error "One layout swap locked test failed"
19821 }
19822 run_test 405 "Various layout swap lock tests"
19823
19824 test_406() {
19825         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19826         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19827         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19829         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19830                 skip "Need MDS version at least 2.8.50"
19831
19832         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19833         local test_pool=$TESTNAME
19834
19835         if ! combined_mgs_mds ; then
19836                 mount_mgs_client
19837         fi
19838         pool_add $test_pool || error "pool_add failed"
19839         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19840                 error "pool_add_targets failed"
19841
19842         save_layout_restore_at_exit $MOUNT
19843
19844         # parent set default stripe count only, child will stripe from both
19845         # parent and fs default
19846         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19847                 error "setstripe $MOUNT failed"
19848         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19849         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19850         for i in $(seq 10); do
19851                 local f=$DIR/$tdir/$tfile.$i
19852                 touch $f || error "touch failed"
19853                 local count=$($LFS getstripe -c $f)
19854                 [ $count -eq $OSTCOUNT ] ||
19855                         error "$f stripe count $count != $OSTCOUNT"
19856                 local offset=$($LFS getstripe -i $f)
19857                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19858                 local size=$($LFS getstripe -S $f)
19859                 [ $size -eq $((def_stripe_size * 2)) ] ||
19860                         error "$f stripe size $size != $((def_stripe_size * 2))"
19861                 local pool=$($LFS getstripe -p $f)
19862                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19863         done
19864
19865         # change fs default striping, delete parent default striping, now child
19866         # will stripe from new fs default striping only
19867         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19868                 error "change $MOUNT default stripe failed"
19869         $LFS setstripe -c 0 $DIR/$tdir ||
19870                 error "delete $tdir default stripe failed"
19871         for i in $(seq 11 20); do
19872                 local f=$DIR/$tdir/$tfile.$i
19873                 touch $f || error "touch $f failed"
19874                 local count=$($LFS getstripe -c $f)
19875                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19876                 local offset=$($LFS getstripe -i $f)
19877                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19878                 local size=$($LFS getstripe -S $f)
19879                 [ $size -eq $def_stripe_size ] ||
19880                         error "$f stripe size $size != $def_stripe_size"
19881                 local pool=$($LFS getstripe -p $f)
19882                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19883         done
19884
19885         unlinkmany $DIR/$tdir/$tfile. 1 20
19886
19887         local f=$DIR/$tdir/$tfile
19888         pool_remove_all_targets $test_pool $f
19889         pool_remove $test_pool $f
19890
19891         if ! combined_mgs_mds ; then
19892                 umount_mgs_client
19893         fi
19894 }
19895 run_test 406 "DNE support fs default striping"
19896
19897 test_407() {
19898         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19899         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19900                 skip "Need MDS version at least 2.8.55"
19901         remote_mds_nodsh && skip "remote MDS with nodsh"
19902
19903         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19904                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19905         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19906                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19907         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19908
19909         #define OBD_FAIL_DT_TXN_STOP    0x2019
19910         for idx in $(seq $MDSCOUNT); do
19911                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19912         done
19913         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19914         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19915                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19916         true
19917 }
19918 run_test 407 "transaction fail should cause operation fail"
19919
19920 test_408() {
19921         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19922
19923         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19924         lctl set_param fail_loc=0x8000040a
19925         # let ll_prepare_partial_page() fail
19926         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19927
19928         rm -f $DIR/$tfile
19929
19930         # create at least 100 unused inodes so that
19931         # shrink_icache_memory(0) should not return 0
19932         touch $DIR/$tfile-{0..100}
19933         rm -f $DIR/$tfile-{0..100}
19934         sync
19935
19936         echo 2 > /proc/sys/vm/drop_caches
19937 }
19938 run_test 408 "drop_caches should not hang due to page leaks"
19939
19940 test_409()
19941 {
19942         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19943
19944         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19945         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19946         touch $DIR/$tdir/guard || error "(2) Fail to create"
19947
19948         local PREFIX=$(str_repeat 'A' 128)
19949         echo "Create 1K hard links start at $(date)"
19950         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19951                 error "(3) Fail to hard link"
19952
19953         echo "Links count should be right although linkEA overflow"
19954         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19955         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19956         [ $linkcount -eq 1001 ] ||
19957                 error "(5) Unexpected hard links count: $linkcount"
19958
19959         echo "List all links start at $(date)"
19960         ls -l $DIR/$tdir/foo > /dev/null ||
19961                 error "(6) Fail to list $DIR/$tdir/foo"
19962
19963         echo "Unlink hard links start at $(date)"
19964         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19965                 error "(7) Fail to unlink"
19966         echo "Unlink hard links finished at $(date)"
19967 }
19968 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19969
19970 test_410()
19971 {
19972         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19973                 skip "Need client version at least 2.9.59"
19974
19975         # Create a file, and stat it from the kernel
19976         local testfile=$DIR/$tfile
19977         touch $testfile
19978
19979         local run_id=$RANDOM
19980         local my_ino=$(stat --format "%i" $testfile)
19981
19982         # Try to insert the module. This will always fail as the
19983         # module is designed to not be inserted.
19984         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19985             &> /dev/null
19986
19987         # Anything but success is a test failure
19988         dmesg | grep -q \
19989             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19990             error "no inode match"
19991 }
19992 run_test 410 "Test inode number returned from kernel thread"
19993
19994 cleanup_test411_cgroup() {
19995         trap 0
19996         rmdir "$1"
19997 }
19998
19999 test_411() {
20000         local cg_basedir=/sys/fs/cgroup/memory
20001         # LU-9966
20002         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
20003                 skip "no setup for cgroup"
20004
20005         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
20006                 error "test file creation failed"
20007         cancel_lru_locks osc
20008
20009         # Create a very small memory cgroup to force a slab allocation error
20010         local cgdir=$cg_basedir/osc_slab_alloc
20011         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
20012         trap "cleanup_test411_cgroup $cgdir" EXIT
20013         echo 2M > $cgdir/memory.kmem.limit_in_bytes
20014         echo 1M > $cgdir/memory.limit_in_bytes
20015
20016         # Should not LBUG, just be killed by oom-killer
20017         # dd will return 0 even allocation failure in some environment.
20018         # So don't check return value
20019         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
20020         cleanup_test411_cgroup $cgdir
20021
20022         return 0
20023 }
20024 run_test 411 "Slab allocation error with cgroup does not LBUG"
20025
20026 test_412() {
20027         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20028         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20029                 skip "Need server version at least 2.10.55"
20030         fi
20031
20032         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
20033                 error "mkdir failed"
20034         $LFS getdirstripe $DIR/$tdir
20035         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20036         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
20037                 error "expect $((MDSCOUT - 1)) get $stripe_index"
20038         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
20039         [ $stripe_count -eq 2 ] ||
20040                 error "expect 2 get $stripe_count"
20041 }
20042 run_test 412 "mkdir on specific MDTs"
20043
20044 test_413a() {
20045         [ $MDSCOUNT -lt 2 ] &&
20046                 skip "We need at least 2 MDTs for this test"
20047
20048         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20049                 skip "Need server version at least 2.10.55"
20050         fi
20051
20052         mkdir $DIR/$tdir || error "mkdir failed"
20053
20054         # find MDT that is the most full
20055         local max=$($LFS df | grep MDT |
20056                 awk 'BEGIN { a=0 }
20057                         { sub("%", "", $5)
20058                           if (0+$5 >= a)
20059                           {
20060                                 a = $5
20061                                 b = $6
20062                           }
20063                         }
20064                      END { split(b, c, ":")
20065                            sub("]", "", c[2])
20066                            print c[2]
20067                          }')
20068
20069         for i in $(seq $((MDSCOUNT - 1))); do
20070                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
20071                         error "mkdir d$i failed"
20072                 $LFS getdirstripe $DIR/$tdir/d$i
20073                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
20074                 [ $stripe_index -ne $max ] ||
20075                         error "don't expect $max"
20076         done
20077 }
20078 run_test 413a "mkdir on less full MDTs"
20079
20080 test_413b() {
20081         [ $MDSCOUNT -lt 2 ] &&
20082                 skip "We need at least 2 MDTs for this test"
20083
20084         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
20085                 skip "Need server version at least 2.12.52"
20086
20087         mkdir $DIR/$tdir || error "mkdir failed"
20088         $LFS setdirstripe -D -i -1 -H space $DIR/$tdir ||
20089                 error "setdirstripe failed"
20090
20091         local qos_prio_free
20092         local qos_threshold_rr
20093         local count
20094
20095         qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
20096         qos_prio_free=${qos_prio_free%%%}
20097         qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr | head -n1)
20098         qos_threshold_rr=${qos_threshold_rr%%%}
20099         qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
20100
20101         stack_trap "$LCTL set_param lmv.*.qos_prio_free=$qos_prio_free" EXIT
20102         stack_trap "$LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr" \
20103                 EXIT
20104         stack_trap "$LCTL set_param lmv.*.qos_maxage=$qos_maxage" EXIT
20105
20106         echo "mkdir with roundrobin"
20107
20108         $LCTL set_param lmv.*.qos_threshold_rr=100
20109         for i in $(seq $((100 * MDSCOUNT))); do
20110                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20111         done
20112         for i in $(seq $MDSCOUNT); do
20113                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20114                         wc -w)
20115                 echo "$count directories created on MDT$((i - 1))"
20116                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
20117         done
20118
20119         rm -rf $DIR/$tdir/*
20120
20121         $LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr
20122         # Shorten statfs result age, so that it can be updated in time
20123         $LCTL set_param lmv.*.qos_maxage=1
20124         sleep_maxage
20125
20126         local ffree
20127         local max
20128         local min
20129         local max_index
20130         local min_index
20131
20132         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree | uniq))
20133         echo "MDT filesfree available: ${ffree[@]}"
20134         max=${ffree[0]}
20135         min=${ffree[0]}
20136         max_index=0
20137         min_index=0
20138         for ((i = 0; i < ${#ffree[@]}; i++)); do
20139                 if [[ ${ffree[i]} -gt $max ]]; then
20140                         max=${ffree[i]}
20141                         max_index=$i
20142                 fi
20143                 if [[ ${ffree[i]} -lt $min ]]; then
20144                         min=${ffree[i]}
20145                         min_index=$i
20146                 fi
20147         done
20148         echo "Min free files: MDT$min_index: $min"
20149         echo "Max free files: MDT$max_index: $max"
20150
20151         [ $min -eq 0 ] && skip "no free files in MDT$min_index"
20152         [ $min -gt 10000000 ] && skip "too much free files in MDT$min_index"
20153
20154         # Check if we need to generate uneven MDTs
20155         test_mkdir -i $min_index -c 1 -p $DIR/$tdir-MDT$min_index
20156         local threshold=10
20157         local diff=$((max - min))
20158         local diff2=$((diff * 100 / min))
20159
20160         echo -n "Check for uneven MDTs: "
20161         echo -n "diff=$diff files ($diff2%) must be > $threshold% ..."
20162
20163         if [ $diff2 -gt $threshold ]; then
20164                 echo "ok"
20165                 echo "Don't need to fill MDT$min_index"
20166         else
20167                 # generate uneven MDTs, create till 25% diff
20168                 echo "no"
20169                 diff2=$((threshold - diff2))
20170                 diff=$((min * diff2 / 100))
20171                 # 50 sec per 10000 files in vm
20172                 [ $diff -gt 40000 ] && [ "$SLOW" = "no" ] &&
20173                         skip "$diff files to create"
20174                 echo "Fill $diff2% diff in MDT$min_index with $diff files"
20175                 local i
20176                 local value="$(generate_string 1024)"
20177                 for i in $(seq $diff); do
20178                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
20179                                 $DIR/$tdir-MDT$min_index/f$i > /dev/null ||
20180                                 error "create f$i failed"
20181                         setfattr -n user.413b -v $value \
20182                                 $DIR/$tdir-MDT$min_index/f$i ||
20183                                 error "setfattr f$i failed"
20184                 done
20185         fi
20186
20187         min=$((100 *MDSCOUNT))
20188         max=0
20189
20190         echo "mkdir with balanced space usage"
20191         $LCTL set_param lmv.*.qos_prio_free=100
20192         for i in $(seq $((100 * MDSCOUNT))); do
20193                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20194         done
20195         for i in $(seq $MDSCOUNT); do
20196                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20197                         wc -w)
20198                 echo "$count directories created on MDT$((i - 1))"
20199                 [ $min -gt $count ] && min=$count
20200                 [ $max -lt $count ] && max=$count
20201         done
20202         [ $((max - min)) -gt $MDSCOUNT ] ||
20203                 error "subdirs shouldn't be evenly distributed"
20204
20205         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20206
20207         $LFS setdirstripe -D -d $DIR/$tdir || error "setdirstripe -d failed"
20208         getfattr -n trusted.dmv $DIR/$tdir && error "default dir layout exists"
20209         true
20210 }
20211 run_test 413b "mkdir with balanced space usage"
20212
20213 test_414() {
20214 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
20215         $LCTL set_param fail_loc=0x80000521
20216         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
20217         rm -f $DIR/$tfile
20218 }
20219 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
20220
20221 test_415() {
20222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20223         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
20224                 skip "Need server version at least 2.11.52"
20225
20226         # LU-11102
20227         local total
20228         local setattr_pid
20229         local start_time
20230         local end_time
20231         local duration
20232
20233         total=500
20234         # this test may be slow on ZFS
20235         [ "$mds1_FSTYPE" == "zfs" ] && total=100
20236
20237         # though this test is designed for striped directory, let's test normal
20238         # directory too since lock is always saved as CoS lock.
20239         test_mkdir $DIR/$tdir || error "mkdir $tdir"
20240         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
20241
20242         (
20243                 while true; do
20244                         touch $DIR/$tdir
20245                 done
20246         ) &
20247         setattr_pid=$!
20248
20249         start_time=$(date +%s)
20250         for i in $(seq $total); do
20251                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
20252                         > /dev/null
20253         done
20254         end_time=$(date +%s)
20255         duration=$((end_time - start_time))
20256
20257         kill -9 $setattr_pid
20258
20259         echo "rename $total files took $duration sec"
20260         [ $duration -lt 100 ] || error "rename took $duration sec"
20261 }
20262 run_test 415 "lock revoke is not missing"
20263
20264 test_416() {
20265         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
20266                 skip "Need server version at least 2.11.55"
20267
20268         # define OBD_FAIL_OSD_TXN_START    0x19a
20269         do_facet mds1 lctl set_param fail_loc=0x19a
20270
20271         lfs mkdir -c $MDSCOUNT $DIR/$tdir
20272
20273         true
20274 }
20275 run_test 416 "transaction start failure won't cause system hung"
20276
20277 cleanup_417() {
20278         trap 0
20279         do_nodes $(comma_list $(mdts_nodes)) \
20280                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
20281         do_nodes $(comma_list $(mdts_nodes)) \
20282                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
20283         do_nodes $(comma_list $(mdts_nodes)) \
20284                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
20285 }
20286
20287 test_417() {
20288         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20289         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
20290                 skip "Need MDS version at least 2.11.56"
20291
20292         trap cleanup_417 RETURN EXIT
20293
20294         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
20295         do_nodes $(comma_list $(mdts_nodes)) \
20296                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
20297         $LFS migrate -m 0 $DIR/$tdir.1 &&
20298                 error "migrate dir $tdir.1 should fail"
20299
20300         do_nodes $(comma_list $(mdts_nodes)) \
20301                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
20302         $LFS mkdir -i 1 $DIR/$tdir.2 &&
20303                 error "create remote dir $tdir.2 should fail"
20304
20305         do_nodes $(comma_list $(mdts_nodes)) \
20306                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
20307         $LFS mkdir -c 2 $DIR/$tdir.3 &&
20308                 error "create striped dir $tdir.3 should fail"
20309         true
20310 }
20311 run_test 417 "disable remote dir, striped dir and dir migration"
20312
20313 # Checks that the outputs of df [-i] and lfs df [-i] match
20314 #
20315 # usage: check_lfs_df <blocks | inodes> <mountpoint>
20316 check_lfs_df() {
20317         local dir=$2
20318         local inodes
20319         local df_out
20320         local lfs_df_out
20321         local count
20322         local passed=false
20323
20324         # blocks or inodes
20325         [ "$1" == "blocks" ] && inodes= || inodes="-i"
20326
20327         for count in {1..100}; do
20328                 cancel_lru_locks
20329                 sync; sleep 0.2
20330
20331                 # read the lines of interest
20332                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
20333                         error "df $inodes $dir | tail -n +2 failed"
20334                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
20335                         error "lfs df $inodes $dir | grep summary: failed"
20336
20337                 # skip first substrings of each output as they are different
20338                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
20339                 # compare the two outputs
20340                 passed=true
20341                 for i in {1..5}; do
20342                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
20343                 done
20344                 $passed && break
20345         done
20346
20347         if ! $passed; then
20348                 df -P $inodes $dir
20349                 echo
20350                 lfs df $inodes $dir
20351                 error "df and lfs df $1 output mismatch: "      \
20352                       "df ${inodes}: ${df_out[*]}, "            \
20353                       "lfs df ${inodes}: ${lfs_df_out[*]}"
20354         fi
20355 }
20356
20357 test_418() {
20358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20359
20360         local dir=$DIR/$tdir
20361         local numfiles=$((RANDOM % 4096 + 2))
20362         local numblocks=$((RANDOM % 256 + 1))
20363
20364         wait_delete_completed
20365         test_mkdir $dir
20366
20367         # check block output
20368         check_lfs_df blocks $dir
20369         # check inode output
20370         check_lfs_df inodes $dir
20371
20372         # create a single file and retest
20373         echo "Creating a single file and testing"
20374         createmany -o $dir/$tfile- 1 &>/dev/null ||
20375                 error "creating 1 file in $dir failed"
20376         check_lfs_df blocks $dir
20377         check_lfs_df inodes $dir
20378
20379         # create a random number of files
20380         echo "Creating $((numfiles - 1)) files and testing"
20381         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
20382                 error "creating $((numfiles - 1)) files in $dir failed"
20383
20384         # write a random number of blocks to the first test file
20385         echo "Writing $numblocks 4K blocks and testing"
20386         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
20387                 count=$numblocks &>/dev/null ||
20388                 error "dd to $dir/${tfile}-0 failed"
20389
20390         # retest
20391         check_lfs_df blocks $dir
20392         check_lfs_df inodes $dir
20393
20394         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
20395                 error "unlinking $numfiles files in $dir failed"
20396 }
20397 run_test 418 "df and lfs df outputs match"
20398
20399 test_419()
20400 {
20401         local dir=$DIR/$tdir
20402
20403         mkdir -p $dir
20404         touch $dir/file
20405
20406         cancel_lru_locks mdc
20407
20408         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
20409         $LCTL set_param fail_loc=0x1410
20410         cat $dir/file
20411         $LCTL set_param fail_loc=0
20412         rm -rf $dir
20413 }
20414 run_test 419 "Verify open file by name doesn't crash kernel"
20415
20416 test_420()
20417 {
20418         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
20419                 skip "Need MDS version at least 2.12.53"
20420
20421         local SAVE_UMASK=$(umask)
20422         local dir=$DIR/$tdir
20423         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
20424
20425         mkdir -p $dir
20426         umask 0000
20427         mkdir -m03777 $dir/testdir
20428         ls -dn $dir/testdir
20429         # Need to remove trailing '.' when SELinux is enabled
20430         local dirperms=$(ls -dn $dir/testdir |
20431                          awk '{ sub(/\.$/, "", $1); print $1}')
20432         [ $dirperms == "drwxrwsrwt" ] ||
20433                 error "incorrect perms on $dir/testdir"
20434
20435         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
20436                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
20437         ls -n $dir/testdir/testfile
20438         local fileperms=$(ls -n $dir/testdir/testfile |
20439                           awk '{ sub(/\.$/, "", $1); print $1}')
20440         [ $fileperms == "-rwxr-xr-x" ] ||
20441                 error "incorrect perms on $dir/testdir/testfile"
20442
20443         umask $SAVE_UMASK
20444 }
20445 run_test 420 "clear SGID bit on non-directories for non-members"
20446
20447 test_421a() {
20448         local cnt
20449         local fid1
20450         local fid2
20451
20452         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20453                 skip "Need MDS version at least 2.12.54"
20454
20455         test_mkdir $DIR/$tdir
20456         createmany -o $DIR/$tdir/f 3
20457         cnt=$(ls -1 $DIR/$tdir | wc -l)
20458         [ $cnt != 3 ] && error "unexpected #files: $cnt"
20459
20460         fid1=$(lfs path2fid $DIR/$tdir/f1)
20461         fid2=$(lfs path2fid $DIR/$tdir/f2)
20462         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
20463
20464         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
20465         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
20466
20467         cnt=$(ls -1 $DIR/$tdir | wc -l)
20468         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
20469
20470         rm -f $DIR/$tdir/f3 || error "can't remove f3"
20471         createmany -o $DIR/$tdir/f 3
20472         cnt=$(ls -1 $DIR/$tdir | wc -l)
20473         [ $cnt != 3 ] && error "unexpected #files: $cnt"
20474
20475         fid1=$(lfs path2fid $DIR/$tdir/f1)
20476         fid2=$(lfs path2fid $DIR/$tdir/f2)
20477         echo "remove using fsname $FSNAME"
20478         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
20479
20480         cnt=$(ls -1 $DIR/$tdir | wc -l)
20481         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
20482 }
20483 run_test 421a "simple rm by fid"
20484
20485 test_421b() {
20486         local cnt
20487         local FID1
20488         local FID2
20489
20490         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20491                 skip "Need MDS version at least 2.12.54"
20492
20493         test_mkdir $DIR/$tdir
20494         createmany -o $DIR/$tdir/f 3
20495         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
20496         MULTIPID=$!
20497
20498         FID1=$(lfs path2fid $DIR/$tdir/f1)
20499         FID2=$(lfs path2fid $DIR/$tdir/f2)
20500         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
20501
20502         kill -USR1 $MULTIPID
20503         wait
20504
20505         cnt=$(ls $DIR/$tdir | wc -l)
20506         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
20507 }
20508 run_test 421b "rm by fid on open file"
20509
20510 test_421c() {
20511         local cnt
20512         local FIDS
20513
20514         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20515                 skip "Need MDS version at least 2.12.54"
20516
20517         test_mkdir $DIR/$tdir
20518         createmany -o $DIR/$tdir/f 3
20519         touch $DIR/$tdir/$tfile
20520         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
20521         cnt=$(ls -1 $DIR/$tdir | wc -l)
20522         [ $cnt != 184 ] && error "unexpected #files: $cnt"
20523
20524         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
20525         $LFS rmfid $DIR $FID1 || error "rmfid failed"
20526
20527         cnt=$(ls $DIR/$tdir | wc -l)
20528         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
20529 }
20530 run_test 421c "rm by fid against hardlinked files"
20531
20532 test_421d() {
20533         local cnt
20534         local FIDS
20535
20536         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20537                 skip "Need MDS version at least 2.12.54"
20538
20539         test_mkdir $DIR/$tdir
20540         createmany -o $DIR/$tdir/f 4097
20541         cnt=$(ls -1 $DIR/$tdir | wc -l)
20542         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
20543
20544         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
20545         $LFS rmfid $DIR $FIDS || error "rmfid failed"
20546
20547         cnt=$(ls $DIR/$tdir | wc -l)
20548         rm -rf $DIR/$tdir
20549         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
20550 }
20551 run_test 421d "rmfid en masse"
20552
20553 test_421e() {
20554         local cnt
20555         local FID
20556
20557         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20558         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20559                 skip "Need MDS version at least 2.12.54"
20560
20561         mkdir -p $DIR/$tdir
20562         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20563         createmany -o $DIR/$tdir/striped_dir/f 512
20564         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
20565         [ $cnt != 512 ] && error "unexpected #files: $cnt"
20566
20567         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
20568                 sed "s/[/][^:]*://g")
20569         $LFS rmfid $DIR $FIDS || error "rmfid failed"
20570
20571         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
20572         rm -rf $DIR/$tdir
20573         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
20574 }
20575 run_test 421e "rmfid in DNE"
20576
20577 test_421f() {
20578         local cnt
20579         local FID
20580
20581         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20582                 skip "Need MDS version at least 2.12.54"
20583
20584         test_mkdir $DIR/$tdir
20585         touch $DIR/$tdir/f
20586         cnt=$(ls -1 $DIR/$tdir | wc -l)
20587         [ $cnt != 1 ] && error "unexpected #files: $cnt"
20588
20589         FID=$(lfs path2fid $DIR/$tdir/f)
20590         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
20591         # rmfid should fail
20592         cnt=$(ls -1 $DIR/$tdir | wc -l)
20593         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
20594
20595         chmod a+rw $DIR/$tdir
20596         ls -la $DIR/$tdir
20597         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
20598         # rmfid should fail
20599         cnt=$(ls -1 $DIR/$tdir | wc -l)
20600         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
20601
20602         rm -f $DIR/$tdir/f
20603         $RUNAS touch $DIR/$tdir/f
20604         FID=$(lfs path2fid $DIR/$tdir/f)
20605         echo "rmfid as root"
20606         $LFS rmfid $DIR $FID || error "rmfid as root failed"
20607         cnt=$(ls -1 $DIR/$tdir | wc -l)
20608         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
20609
20610         rm -f $DIR/$tdir/f
20611         $RUNAS touch $DIR/$tdir/f
20612         cnt=$(ls -1 $DIR/$tdir | wc -l)
20613         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
20614         FID=$(lfs path2fid $DIR/$tdir/f)
20615         # rmfid w/o user_fid2path mount option should fail
20616         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
20617         cnt=$(ls -1 $DIR/$tdir | wc -l)
20618         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
20619
20620         umount_client $MOUNT || "failed to umount client"
20621         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
20622                 "failed to mount client'"
20623
20624         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
20625         # rmfid should succeed
20626         cnt=$(ls -1 $DIR/$tdir | wc -l)
20627         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
20628
20629         # rmfid shouldn't allow to remove files due to dir's permission
20630         chmod a+rwx $DIR/$tdir
20631         touch $DIR/$tdir/f
20632         ls -la $DIR/$tdir
20633         FID=$(lfs path2fid $DIR/$tdir/f)
20634         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
20635
20636         umount_client $MOUNT || "failed to umount client"
20637         mount_client $MOUNT "$MOUNT_OPTS" ||
20638                 "failed to mount client'"
20639
20640 }
20641 run_test 421f "rmfid checks permissions"
20642
20643 test_421g() {
20644         local cnt
20645         local FIDS
20646
20647         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20648         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20649                 skip "Need MDS version at least 2.12.54"
20650
20651         mkdir -p $DIR/$tdir
20652         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20653         createmany -o $DIR/$tdir/striped_dir/f 512
20654         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
20655         [ $cnt != 512 ] && error "unexpected #files: $cnt"
20656
20657         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
20658                 sed "s/[/][^:]*://g")
20659
20660         rm -f $DIR/$tdir/striped_dir/f1*
20661         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
20662         removed=$((512 - cnt))
20663
20664         # few files have been just removed, so we expect
20665         # rmfid to fail on their fids
20666         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
20667         [ $removed != $errors ] && error "$errors != $removed"
20668
20669         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
20670         rm -rf $DIR/$tdir
20671         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
20672 }
20673 run_test 421g "rmfid to return errors properly"
20674
20675 prep_801() {
20676         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20677         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20678                 skip "Need server version at least 2.9.55"
20679
20680         start_full_debug_logging
20681 }
20682
20683 post_801() {
20684         stop_full_debug_logging
20685 }
20686
20687 barrier_stat() {
20688         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20689                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20690                            awk '/The barrier for/ { print $7 }')
20691                 echo $st
20692         else
20693                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
20694                 echo \'$st\'
20695         fi
20696 }
20697
20698 barrier_expired() {
20699         local expired
20700
20701         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20702                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20703                           awk '/will be expired/ { print $7 }')
20704         else
20705                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
20706         fi
20707
20708         echo $expired
20709 }
20710
20711 test_801a() {
20712         prep_801
20713
20714         echo "Start barrier_freeze at: $(date)"
20715         #define OBD_FAIL_BARRIER_DELAY          0x2202
20716         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20717         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
20718
20719         sleep 2
20720         local b_status=$(barrier_stat)
20721         echo "Got barrier status at: $(date)"
20722         [ "$b_status" = "'freezing_p1'" ] ||
20723                 error "(1) unexpected barrier status $b_status"
20724
20725         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20726         wait
20727         b_status=$(barrier_stat)
20728         [ "$b_status" = "'frozen'" ] ||
20729                 error "(2) unexpected barrier status $b_status"
20730
20731         local expired=$(barrier_expired)
20732         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
20733         sleep $((expired + 3))
20734
20735         b_status=$(barrier_stat)
20736         [ "$b_status" = "'expired'" ] ||
20737                 error "(3) unexpected barrier status $b_status"
20738
20739         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
20740                 error "(4) fail to freeze barrier"
20741
20742         b_status=$(barrier_stat)
20743         [ "$b_status" = "'frozen'" ] ||
20744                 error "(5) unexpected barrier status $b_status"
20745
20746         echo "Start barrier_thaw at: $(date)"
20747         #define OBD_FAIL_BARRIER_DELAY          0x2202
20748         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20749         do_facet mgs $LCTL barrier_thaw $FSNAME &
20750
20751         sleep 2
20752         b_status=$(barrier_stat)
20753         echo "Got barrier status at: $(date)"
20754         [ "$b_status" = "'thawing'" ] ||
20755                 error "(6) unexpected barrier status $b_status"
20756
20757         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20758         wait
20759         b_status=$(barrier_stat)
20760         [ "$b_status" = "'thawed'" ] ||
20761                 error "(7) unexpected barrier status $b_status"
20762
20763         #define OBD_FAIL_BARRIER_FAILURE        0x2203
20764         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
20765         do_facet mgs $LCTL barrier_freeze $FSNAME
20766
20767         b_status=$(barrier_stat)
20768         [ "$b_status" = "'failed'" ] ||
20769                 error "(8) unexpected barrier status $b_status"
20770
20771         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20772         do_facet mgs $LCTL barrier_thaw $FSNAME
20773
20774         post_801
20775 }
20776 run_test 801a "write barrier user interfaces and stat machine"
20777
20778 test_801b() {
20779         prep_801
20780
20781         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20782         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
20783         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
20784         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
20785         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
20786
20787         cancel_lru_locks mdc
20788
20789         # 180 seconds should be long enough
20790         do_facet mgs $LCTL barrier_freeze $FSNAME 180
20791
20792         local b_status=$(barrier_stat)
20793         [ "$b_status" = "'frozen'" ] ||
20794                 error "(6) unexpected barrier status $b_status"
20795
20796         mkdir $DIR/$tdir/d0/d10 &
20797         mkdir_pid=$!
20798
20799         touch $DIR/$tdir/d1/f13 &
20800         touch_pid=$!
20801
20802         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
20803         ln_pid=$!
20804
20805         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
20806         mv_pid=$!
20807
20808         rm -f $DIR/$tdir/d4/f12 &
20809         rm_pid=$!
20810
20811         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
20812
20813         # To guarantee taht the 'stat' is not blocked
20814         b_status=$(barrier_stat)
20815         [ "$b_status" = "'frozen'" ] ||
20816                 error "(8) unexpected barrier status $b_status"
20817
20818         # let above commands to run at background
20819         sleep 5
20820
20821         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
20822         ps -p $touch_pid || error "(10) touch should be blocked"
20823         ps -p $ln_pid || error "(11) link should be blocked"
20824         ps -p $mv_pid || error "(12) rename should be blocked"
20825         ps -p $rm_pid || error "(13) unlink should be blocked"
20826
20827         b_status=$(barrier_stat)
20828         [ "$b_status" = "'frozen'" ] ||
20829                 error "(14) unexpected barrier status $b_status"
20830
20831         do_facet mgs $LCTL barrier_thaw $FSNAME
20832         b_status=$(barrier_stat)
20833         [ "$b_status" = "'thawed'" ] ||
20834                 error "(15) unexpected barrier status $b_status"
20835
20836         wait $mkdir_pid || error "(16) mkdir should succeed"
20837         wait $touch_pid || error "(17) touch should succeed"
20838         wait $ln_pid || error "(18) link should succeed"
20839         wait $mv_pid || error "(19) rename should succeed"
20840         wait $rm_pid || error "(20) unlink should succeed"
20841
20842         post_801
20843 }
20844 run_test 801b "modification will be blocked by write barrier"
20845
20846 test_801c() {
20847         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20848
20849         prep_801
20850
20851         stop mds2 || error "(1) Fail to stop mds2"
20852
20853         do_facet mgs $LCTL barrier_freeze $FSNAME 30
20854
20855         local b_status=$(barrier_stat)
20856         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
20857                 do_facet mgs $LCTL barrier_thaw $FSNAME
20858                 error "(2) unexpected barrier status $b_status"
20859         }
20860
20861         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20862                 error "(3) Fail to rescan barrier bitmap"
20863
20864         do_facet mgs $LCTL barrier_freeze $FSNAME 10
20865
20866         b_status=$(barrier_stat)
20867         [ "$b_status" = "'frozen'" ] ||
20868                 error "(4) unexpected barrier status $b_status"
20869
20870         do_facet mgs $LCTL barrier_thaw $FSNAME
20871         b_status=$(barrier_stat)
20872         [ "$b_status" = "'thawed'" ] ||
20873                 error "(5) unexpected barrier status $b_status"
20874
20875         local devname=$(mdsdevname 2)
20876
20877         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
20878
20879         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20880                 error "(7) Fail to rescan barrier bitmap"
20881
20882         post_801
20883 }
20884 run_test 801c "rescan barrier bitmap"
20885
20886 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
20887 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
20888 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
20889 saved_MOUNT_OPTS=$MOUNT_OPTS
20890
20891 cleanup_802a() {
20892         trap 0
20893
20894         stopall
20895         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
20896         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
20897         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
20898         MOUNT_OPTS=$saved_MOUNT_OPTS
20899         setupall
20900 }
20901
20902 test_802a() {
20903
20904         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20905         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20906                 skip "Need server version at least 2.9.55"
20907
20908         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
20909
20910         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20911
20912         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20913                 error "(2) Fail to copy"
20914
20915         trap cleanup_802a EXIT
20916
20917         # sync by force before remount as readonly
20918         sync; sync_all_data; sleep 3; sync_all_data
20919
20920         stopall
20921
20922         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
20923         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
20924         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
20925
20926         echo "Mount the server as read only"
20927         setupall server_only || error "(3) Fail to start servers"
20928
20929         echo "Mount client without ro should fail"
20930         mount_client $MOUNT &&
20931                 error "(4) Mount client without 'ro' should fail"
20932
20933         echo "Mount client with ro should succeed"
20934         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
20935         mount_client $MOUNT ||
20936                 error "(5) Mount client with 'ro' should succeed"
20937
20938         echo "Modify should be refused"
20939         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20940
20941         echo "Read should be allowed"
20942         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20943                 error "(7) Read should succeed under ro mode"
20944
20945         cleanup_802a
20946 }
20947 run_test 802a "simulate readonly device"
20948
20949 test_802b() {
20950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20951         remote_mds_nodsh && skip "remote MDS with nodsh"
20952
20953         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
20954                 skip "readonly option not available"
20955
20956         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
20957
20958         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20959                 error "(2) Fail to copy"
20960
20961         # write back all cached data before setting MDT to readonly
20962         cancel_lru_locks
20963         sync_all_data
20964
20965         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
20966         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
20967
20968         echo "Modify should be refused"
20969         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20970
20971         echo "Read should be allowed"
20972         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20973                 error "(7) Read should succeed under ro mode"
20974
20975         # disable readonly
20976         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
20977 }
20978 run_test 802b "be able to set MDTs to readonly"
20979
20980 test_803() {
20981         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20982         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20983                 skip "MDS needs to be newer than 2.10.54"
20984
20985         mkdir -p $DIR/$tdir
20986         # Create some objects on all MDTs to trigger related logs objects
20987         for idx in $(seq $MDSCOUNT); do
20988                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
20989                         $DIR/$tdir/dir${idx} ||
20990                         error "Fail to create $DIR/$tdir/dir${idx}"
20991         done
20992
20993         sync; sleep 3
20994         wait_delete_completed # ensure old test cleanups are finished
20995         echo "before create:"
20996         $LFS df -i $MOUNT
20997         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20998
20999         for i in {1..10}; do
21000                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
21001                         error "Fail to create $DIR/$tdir/foo$i"
21002         done
21003
21004         sync; sleep 3
21005         echo "after create:"
21006         $LFS df -i $MOUNT
21007         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21008
21009         # allow for an llog to be cleaned up during the test
21010         [ $after_used -ge $((before_used + 10 - 1)) ] ||
21011                 error "before ($before_used) + 10 > after ($after_used)"
21012
21013         for i in {1..10}; do
21014                 rm -rf $DIR/$tdir/foo$i ||
21015                         error "Fail to remove $DIR/$tdir/foo$i"
21016         done
21017
21018         sleep 3 # avoid MDT return cached statfs
21019         wait_delete_completed
21020         echo "after unlink:"
21021         $LFS df -i $MOUNT
21022         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21023
21024         # allow for an llog to be created during the test
21025         [ $after_used -le $((before_used + 1)) ] ||
21026                 error "after ($after_used) > before ($before_used) + 1"
21027 }
21028 run_test 803 "verify agent object for remote object"
21029
21030 test_804() {
21031         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21032         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21033                 skip "MDS needs to be newer than 2.10.54"
21034         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21035
21036         mkdir -p $DIR/$tdir
21037         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
21038                 error "Fail to create $DIR/$tdir/dir0"
21039
21040         local fid=$($LFS path2fid $DIR/$tdir/dir0)
21041         local dev=$(mdsdevname 2)
21042
21043         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21044                 grep ${fid} || error "NOT found agent entry for dir0"
21045
21046         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
21047                 error "Fail to create $DIR/$tdir/dir1"
21048
21049         touch $DIR/$tdir/dir1/foo0 ||
21050                 error "Fail to create $DIR/$tdir/dir1/foo0"
21051         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
21052         local rc=0
21053
21054         for idx in $(seq $MDSCOUNT); do
21055                 dev=$(mdsdevname $idx)
21056                 do_facet mds${idx} \
21057                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21058                         grep ${fid} && rc=$idx
21059         done
21060
21061         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
21062                 error "Fail to rename foo0 to foo1"
21063         if [ $rc -eq 0 ]; then
21064                 for idx in $(seq $MDSCOUNT); do
21065                         dev=$(mdsdevname $idx)
21066                         do_facet mds${idx} \
21067                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21068                         grep ${fid} && rc=$idx
21069                 done
21070         fi
21071
21072         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
21073                 error "Fail to rename foo1 to foo2"
21074         if [ $rc -eq 0 ]; then
21075                 for idx in $(seq $MDSCOUNT); do
21076                         dev=$(mdsdevname $idx)
21077                         do_facet mds${idx} \
21078                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21079                         grep ${fid} && rc=$idx
21080                 done
21081         fi
21082
21083         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
21084
21085         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
21086                 error "Fail to link to $DIR/$tdir/dir1/foo2"
21087         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
21088                 error "Fail to rename foo2 to foo0"
21089         unlink $DIR/$tdir/dir1/foo0 ||
21090                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
21091         rm -rf $DIR/$tdir/dir0 ||
21092                 error "Fail to rm $DIR/$tdir/dir0"
21093
21094         for idx in $(seq $MDSCOUNT); do
21095                 dev=$(mdsdevname $idx)
21096                 rc=0
21097
21098                 stop mds${idx}
21099                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
21100                         rc=$?
21101                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
21102                         error "mount mds$idx failed"
21103                 df $MOUNT > /dev/null 2>&1
21104
21105                 # e2fsck should not return error
21106                 [ $rc -eq 0 ] ||
21107                         error "e2fsck detected error on MDT${idx}: rc=$rc"
21108         done
21109 }
21110 run_test 804 "verify agent entry for remote entry"
21111
21112 cleanup_805() {
21113         do_facet $SINGLEMDS zfs set quota=$old $fsset
21114         unlinkmany $DIR/$tdir/f- 1000000
21115         trap 0
21116 }
21117
21118 test_805() {
21119         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
21120         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
21121         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
21122                 skip "netfree not implemented before 0.7"
21123         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
21124                 skip "Need MDS version at least 2.10.57"
21125
21126         local fsset
21127         local freekb
21128         local usedkb
21129         local old
21130         local quota
21131         local pref="osd-zfs.lustre-MDT0000."
21132
21133         # limit available space on MDS dataset to meet nospace issue
21134         # quickly. then ZFS 0.7.2 can use reserved space if asked
21135         # properly (using netfree flag in osd_declare_destroy()
21136         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
21137         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
21138                 gawk '{print $3}')
21139         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
21140         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
21141         let "usedkb=usedkb-freekb"
21142         let "freekb=freekb/2"
21143         if let "freekb > 5000"; then
21144                 let "freekb=5000"
21145         fi
21146         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
21147         trap cleanup_805 EXIT
21148         mkdir $DIR/$tdir
21149         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
21150         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
21151         rm -rf $DIR/$tdir || error "not able to remove"
21152         do_facet $SINGLEMDS zfs set quota=$old $fsset
21153         trap 0
21154 }
21155 run_test 805 "ZFS can remove from full fs"
21156
21157 # Size-on-MDS test
21158 check_lsom_data()
21159 {
21160         local file=$1
21161         local size=$($LFS getsom -s $file)
21162         local expect=$(stat -c %s $file)
21163
21164         [[ $size == $expect ]] ||
21165                 error "$file expected size: $expect, got: $size"
21166
21167         local blocks=$($LFS getsom -b $file)
21168         expect=$(stat -c %b $file)
21169         [[ $blocks == $expect ]] ||
21170                 error "$file expected blocks: $expect, got: $blocks"
21171 }
21172
21173 check_lsom_size()
21174 {
21175         local size=$($LFS getsom -s $1)
21176         local expect=$2
21177
21178         [[ $size == $expect ]] ||
21179                 error "$file expected size: $expect, got: $size"
21180 }
21181
21182 test_806() {
21183         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21184                 skip "Need MDS version at least 2.11.52"
21185
21186         local bs=1048576
21187
21188         touch $DIR/$tfile || error "touch $tfile failed"
21189
21190         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21191         save_lustre_params client "llite.*.xattr_cache" > $save
21192         lctl set_param llite.*.xattr_cache=0
21193         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21194
21195         # single-threaded write
21196         echo "Test SOM for single-threaded write"
21197         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
21198                 error "write $tfile failed"
21199         check_lsom_size $DIR/$tfile $bs
21200
21201         local num=32
21202         local size=$(($num * $bs))
21203         local offset=0
21204         local i
21205
21206         echo "Test SOM for single client multi-threaded($num) write"
21207         $TRUNCATE $DIR/$tfile 0
21208         for ((i = 0; i < $num; i++)); do
21209                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21210                 local pids[$i]=$!
21211                 offset=$((offset + $bs))
21212         done
21213         for (( i=0; i < $num; i++ )); do
21214                 wait ${pids[$i]}
21215         done
21216         check_lsom_size $DIR/$tfile $size
21217
21218         $TRUNCATE $DIR/$tfile 0
21219         for ((i = 0; i < $num; i++)); do
21220                 offset=$((offset - $bs))
21221                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21222                 local pids[$i]=$!
21223         done
21224         for (( i=0; i < $num; i++ )); do
21225                 wait ${pids[$i]}
21226         done
21227         check_lsom_size $DIR/$tfile $size
21228
21229         # multi-client wirtes
21230         num=$(get_node_count ${CLIENTS//,/ })
21231         size=$(($num * $bs))
21232         offset=0
21233         i=0
21234
21235         echo "Test SOM for multi-client ($num) writes"
21236         $TRUNCATE $DIR/$tfile 0
21237         for client in ${CLIENTS//,/ }; do
21238                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21239                 local pids[$i]=$!
21240                 i=$((i + 1))
21241                 offset=$((offset + $bs))
21242         done
21243         for (( i=0; i < $num; i++ )); do
21244                 wait ${pids[$i]}
21245         done
21246         check_lsom_size $DIR/$tfile $offset
21247
21248         i=0
21249         $TRUNCATE $DIR/$tfile 0
21250         for client in ${CLIENTS//,/ }; do
21251                 offset=$((offset - $bs))
21252                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21253                 local pids[$i]=$!
21254                 i=$((i + 1))
21255         done
21256         for (( i=0; i < $num; i++ )); do
21257                 wait ${pids[$i]}
21258         done
21259         check_lsom_size $DIR/$tfile $size
21260
21261         # verify truncate
21262         echo "Test SOM for truncate"
21263         $TRUNCATE $DIR/$tfile 1048576
21264         check_lsom_size $DIR/$tfile 1048576
21265         $TRUNCATE $DIR/$tfile 1234
21266         check_lsom_size $DIR/$tfile 1234
21267
21268         # verify SOM blocks count
21269         echo "Verify SOM block count"
21270         $TRUNCATE $DIR/$tfile 0
21271         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
21272                 error "failed to write file $tfile"
21273         check_lsom_data $DIR/$tfile
21274 }
21275 run_test 806 "Verify Lazy Size on MDS"
21276
21277 test_807() {
21278         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
21279         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21280                 skip "Need MDS version at least 2.11.52"
21281
21282         # Registration step
21283         changelog_register || error "changelog_register failed"
21284         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
21285         changelog_users $SINGLEMDS | grep -q $cl_user ||
21286                 error "User $cl_user not found in changelog_users"
21287
21288         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21289         save_lustre_params client "llite.*.xattr_cache" > $save
21290         lctl set_param llite.*.xattr_cache=0
21291         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21292
21293         rm -rf $DIR/$tdir || error "rm $tdir failed"
21294         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21295         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
21296         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
21297         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
21298                 error "truncate $tdir/trunc failed"
21299
21300         local bs=1048576
21301         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
21302                 error "write $tfile failed"
21303
21304         # multi-client wirtes
21305         local num=$(get_node_count ${CLIENTS//,/ })
21306         local offset=0
21307         local i=0
21308
21309         echo "Test SOM for multi-client ($num) writes"
21310         touch $DIR/$tfile || error "touch $tfile failed"
21311         $TRUNCATE $DIR/$tfile 0
21312         for client in ${CLIENTS//,/ }; do
21313                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21314                 local pids[$i]=$!
21315                 i=$((i + 1))
21316                 offset=$((offset + $bs))
21317         done
21318         for (( i=0; i < $num; i++ )); do
21319                 wait ${pids[$i]}
21320         done
21321
21322         sleep 5
21323         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
21324         check_lsom_data $DIR/$tdir/trunc
21325         check_lsom_data $DIR/$tdir/single_dd
21326         check_lsom_data $DIR/$tfile
21327
21328         rm -rf $DIR/$tdir
21329         # Deregistration step
21330         changelog_deregister || error "changelog_deregister failed"
21331 }
21332 run_test 807 "verify LSOM syncing tool"
21333
21334 check_som_nologged()
21335 {
21336         local lines=$($LFS changelog $FSNAME-MDT0000 |
21337                 grep 'x=trusted.som' | wc -l)
21338         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
21339 }
21340
21341 test_808() {
21342         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
21343                 skip "Need MDS version at least 2.11.55"
21344
21345         # Registration step
21346         changelog_register || error "changelog_register failed"
21347
21348         touch $DIR/$tfile || error "touch $tfile failed"
21349         check_som_nologged
21350
21351         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
21352                 error "write $tfile failed"
21353         check_som_nologged
21354
21355         $TRUNCATE $DIR/$tfile 1234
21356         check_som_nologged
21357
21358         $TRUNCATE $DIR/$tfile 1048576
21359         check_som_nologged
21360
21361         # Deregistration step
21362         changelog_deregister || error "changelog_deregister failed"
21363 }
21364 run_test 808 "Check trusted.som xattr not logged in Changelogs"
21365
21366 check_som_nodata()
21367 {
21368         $LFS getsom $1
21369         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
21370 }
21371
21372 test_809() {
21373         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21374                 skip "Need MDS version at least 2.11.56"
21375
21376         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
21377                 error "failed to create DoM-only file $DIR/$tfile"
21378         touch $DIR/$tfile || error "touch $tfile failed"
21379         check_som_nodata $DIR/$tfile
21380
21381         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
21382                 error "write $tfile failed"
21383         check_som_nodata $DIR/$tfile
21384
21385         $TRUNCATE $DIR/$tfile 1234
21386         check_som_nodata $DIR/$tfile
21387
21388         $TRUNCATE $DIR/$tfile 4097
21389         check_som_nodata $DIR/$file
21390 }
21391 run_test 809 "Verify no SOM xattr store for DoM-only files"
21392
21393 test_810() {
21394         local ORIG
21395         local CSUM
21396
21397         # t10 seem to dislike partial pages
21398         lctl set_param osc.*.checksum_type=adler
21399         lctl set_param fail_loc=0x411
21400         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
21401         ORIG=$(md5sum $DIR/$tfile)
21402         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
21403         CSUM=$(md5sum $DIR/$tfile)
21404         set_checksum_type adler
21405         if [ "$ORIG" != "$CSUM" ]; then
21406                 error "$ORIG != $CSUM"
21407         fi
21408 }
21409 run_test 810 "partial page writes on ZFS (LU-11663)"
21410
21411 test_811() {
21412         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
21413                 skip "Need MDS version at least 2.11.56"
21414
21415         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
21416         do_facet mds1 $LCTL set_param fail_loc=0x165
21417         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
21418
21419         stop mds1
21420         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21421
21422         sleep 5
21423         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
21424                 error "MDD orphan cleanup thread not quit"
21425 }
21426 run_test 811 "orphan name stub can be cleaned up in startup"
21427
21428 test_812() {
21429         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
21430                 skip "OST < 2.12.51 doesn't support this fail_loc"
21431         [ "$SHARED_KEY" = true ] &&
21432                 skip "OSC connections never go IDLE with Shared-Keys enabled"
21433
21434         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21435         # ensure ost1 is connected
21436         stat $DIR/$tfile >/dev/null || error "can't stat"
21437         wait_osc_import_state client ost1 FULL
21438         # no locks, no reqs to let the connection idle
21439         cancel_lru_locks osc
21440
21441         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
21442 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
21443         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
21444         wait_osc_import_state client ost1 CONNECTING
21445         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
21446
21447         stat $DIR/$tfile >/dev/null || error "can't stat file"
21448 }
21449 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
21450
21451 test_813() {
21452         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
21453         [ -z "$file_heat_sav" ] && skip "no file heat support"
21454
21455         local readsample
21456         local writesample
21457         local readbyte
21458         local writebyte
21459         local readsample1
21460         local writesample1
21461         local readbyte1
21462         local writebyte1
21463
21464         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
21465         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
21466
21467         $LCTL set_param -n llite.*.file_heat=1
21468         echo "Turn on file heat"
21469         echo "Period second: $period_second, Decay percentage: $decay_pct"
21470
21471         echo "QQQQ" > $DIR/$tfile
21472         echo "QQQQ" > $DIR/$tfile
21473         echo "QQQQ" > $DIR/$tfile
21474         cat $DIR/$tfile > /dev/null
21475         cat $DIR/$tfile > /dev/null
21476         cat $DIR/$tfile > /dev/null
21477         cat $DIR/$tfile > /dev/null
21478
21479         local out=$($LFS heat_get $DIR/$tfile)
21480
21481         $LFS heat_get $DIR/$tfile
21482         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21483         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21484         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21485         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21486
21487         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
21488         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
21489         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
21490         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
21491
21492         sleep $((period_second + 3))
21493         echo "Sleep $((period_second + 3)) seconds..."
21494         # The recursion formula to calculate the heat of the file f is as
21495         # follow:
21496         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
21497         # Where Hi is the heat value in the period between time points i*I and
21498         # (i+1)*I; Ci is the access count in the period; the symbol P refers
21499         # to the weight of Ci.
21500         out=$($LFS heat_get $DIR/$tfile)
21501         $LFS heat_get $DIR/$tfile
21502         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21503         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21504         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21505         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21506
21507         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
21508                 error "read sample ($readsample) is wrong"
21509         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
21510                 error "write sample ($writesample) is wrong"
21511         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
21512                 error "read bytes ($readbyte) is wrong"
21513         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
21514                 error "write bytes ($writebyte) is wrong"
21515
21516         echo "QQQQ" > $DIR/$tfile
21517         echo "QQQQ" > $DIR/$tfile
21518         echo "QQQQ" > $DIR/$tfile
21519         cat $DIR/$tfile > /dev/null
21520         cat $DIR/$tfile > /dev/null
21521         cat $DIR/$tfile > /dev/null
21522         cat $DIR/$tfile > /dev/null
21523
21524         sleep $((period_second + 3))
21525         echo "Sleep $((period_second + 3)) seconds..."
21526
21527         out=$($LFS heat_get $DIR/$tfile)
21528         $LFS heat_get $DIR/$tfile
21529         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21530         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21531         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21532         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21533
21534         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
21535                 4 * $decay_pct) / 100") -eq 1 ] ||
21536                 error "read sample ($readsample1) is wrong"
21537         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
21538                 3 * $decay_pct) / 100") -eq 1 ] ||
21539                 error "write sample ($writesample1) is wrong"
21540         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
21541                 20 * $decay_pct) / 100") -eq 1 ] ||
21542                 error "read bytes ($readbyte1) is wrong"
21543         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
21544                 15 * $decay_pct) / 100") -eq 1 ] ||
21545                 error "write bytes ($writebyte1) is wrong"
21546
21547         echo "Turn off file heat for the file $DIR/$tfile"
21548         $LFS heat_set -o $DIR/$tfile
21549
21550         echo "QQQQ" > $DIR/$tfile
21551         echo "QQQQ" > $DIR/$tfile
21552         echo "QQQQ" > $DIR/$tfile
21553         cat $DIR/$tfile > /dev/null
21554         cat $DIR/$tfile > /dev/null
21555         cat $DIR/$tfile > /dev/null
21556         cat $DIR/$tfile > /dev/null
21557
21558         out=$($LFS heat_get $DIR/$tfile)
21559         $LFS heat_get $DIR/$tfile
21560         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21561         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21562         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21563         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21564
21565         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21566         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21567         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21568         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21569
21570         echo "Trun on file heat for the file $DIR/$tfile"
21571         $LFS heat_set -O $DIR/$tfile
21572
21573         echo "QQQQ" > $DIR/$tfile
21574         echo "QQQQ" > $DIR/$tfile
21575         echo "QQQQ" > $DIR/$tfile
21576         cat $DIR/$tfile > /dev/null
21577         cat $DIR/$tfile > /dev/null
21578         cat $DIR/$tfile > /dev/null
21579         cat $DIR/$tfile > /dev/null
21580
21581         out=$($LFS heat_get $DIR/$tfile)
21582         $LFS heat_get $DIR/$tfile
21583         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21584         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21585         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21586         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21587
21588         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
21589         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
21590         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
21591         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
21592
21593         $LFS heat_set -c $DIR/$tfile
21594         $LCTL set_param -n llite.*.file_heat=0
21595         echo "Turn off file heat support for the Lustre filesystem"
21596
21597         echo "QQQQ" > $DIR/$tfile
21598         echo "QQQQ" > $DIR/$tfile
21599         echo "QQQQ" > $DIR/$tfile
21600         cat $DIR/$tfile > /dev/null
21601         cat $DIR/$tfile > /dev/null
21602         cat $DIR/$tfile > /dev/null
21603         cat $DIR/$tfile > /dev/null
21604
21605         out=$($LFS heat_get $DIR/$tfile)
21606         $LFS heat_get $DIR/$tfile
21607         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21608         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21609         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21610         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21611
21612         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21613         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21614         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21615         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21616
21617         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
21618         rm -f $DIR/$tfile
21619 }
21620 run_test 813 "File heat verfication"
21621
21622 test_814()
21623 {
21624         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
21625         echo -n y >> $DIR/$tfile
21626         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
21627         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
21628 }
21629 run_test 814 "sparse cp works as expected (LU-12361)"
21630
21631 test_815()
21632 {
21633         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
21634         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
21635 }
21636 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
21637
21638 test_816() {
21639         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21640         # ensure ost1 is connected
21641         stat $DIR/$tfile >/dev/null || error "can't stat"
21642         wait_osc_import_state client ost1 FULL
21643         # no locks, no reqs to let the connection idle
21644         cancel_lru_locks osc
21645         lru_resize_disable osc
21646         local before
21647         local now
21648         before=$($LCTL get_param -n \
21649                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
21650
21651         wait_osc_import_state client ost1 IDLE
21652         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
21653         now=$($LCTL get_param -n \
21654               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
21655         [ $before == $now ] || error "lru_size changed $before != $now"
21656 }
21657 run_test 816 "do not reset lru_resize on idle reconnect"
21658
21659 cleanup_817() {
21660         umount $tmpdir
21661         exportfs -u localhost:$DIR/nfsexp
21662         rm -rf $DIR/nfsexp
21663 }
21664
21665 test_817() {
21666         systemctl restart nfs-server.service || skip "failed to restart nfsd"
21667
21668         mkdir -p $DIR/nfsexp
21669         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
21670                 error "failed to export nfs"
21671
21672         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
21673         stack_trap cleanup_817 EXIT
21674
21675         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
21676                 error "failed to mount nfs to $tmpdir"
21677
21678         cp /bin/true $tmpdir
21679         $DIR/nfsexp/true || error "failed to execute 'true' command"
21680 }
21681 run_test 817 "nfsd won't cache write lock for exec file"
21682
21683 #
21684 # tests that do cleanup/setup should be run at the end
21685 #
21686
21687 test_900() {
21688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21689         local ls
21690
21691         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
21692         $LCTL set_param fail_loc=0x903
21693
21694         cancel_lru_locks MGC
21695
21696         FAIL_ON_ERROR=true cleanup
21697         FAIL_ON_ERROR=true setup
21698 }
21699 run_test 900 "umount should not race with any mgc requeue thread"
21700
21701 complete $SECONDS
21702 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
21703 check_and_cleanup_lustre
21704 if [ "$I_MOUNTED" != "yes" ]; then
21705         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
21706 fi
21707 exit_status