Whamcloud - gitweb
LU-10602 llite: add file heat support
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 # -*- tab-width: 8; indent-tabs-mode: t; -*-
3 #
4 # Run select tests by setting ONLY, or as arguments to the script.
5 # Skip specific tests by setting EXCEPT.
6 #
7 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
8 set -e
9
10 ONLY=${ONLY:-"$*"}
11 # bug number for skipped test: LU-9693 LU-6493 LU-9693
12 ALWAYS_EXCEPT="$SANITY_EXCEPT  42a     42b     42c"
13 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
14
15 # skipped tests: LU-8411 LU-9096 LU-9054 ..
16 ALWAYS_EXCEPT="  407     253     312     $ALWAYS_EXCEPT"
17
18 if $SHARED_KEY; then
19 # bug number for skipped tests: LU-9795 (all below)
20         ALWAYS_EXCEPT="$ALWAYS_EXCEPT   17n     60a     133g    300f"
21 fi
22
23 # Check Grants after these tests
24 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
25
26 # skip the grant tests for ARM until they are fixed
27 if [[ $(uname -m) = aarch64 ]]; then
28         # bug number:    LU-11596 (all below)
29         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
30         # bug number:    LU-11671 LU-11594 LU-11667 LU-11729
31         ALWAYS_EXCEPT+=" 45       103a      317      810"
32 fi
33
34 SRCDIR=$(cd $(dirname $0); echo $PWD)
35 export PATH=$PATH:/sbin
36
37 TMP=${TMP:-/tmp}
38 OSC=${OSC:-"osc"}
39
40 CC=${CC:-cc}
41 CHECKSTAT=${CHECKSTAT:-"checkstat -v"}
42 CREATETEST=${CREATETEST:-createtest}
43 LFS=${LFS:-lfs}
44 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
45 LCTL=${LCTL:-lctl}
46 OPENFILE=${OPENFILE:-openfile}
47 OPENUNLINK=${OPENUNLINK:-openunlink}
48 export MULTIOP=${MULTIOP:-multiop}
49 READS=${READS:-"reads"}
50 MUNLINK=${MUNLINK:-munlink}
51 SOCKETSERVER=${SOCKETSERVER:-socketserver}
52 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
53 MEMHOG=${MEMHOG:-memhog}
54 DIRECTIO=${DIRECTIO:-directio}
55 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
56 DEF_STRIPE_COUNT=-1
57 CHECK_GRANT=${CHECK_GRANT:-"yes"}
58 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
59 export PARALLEL=${PARALLEL:-"no"}
60
61 export NAME=${NAME:-local}
62
63 SAVE_PWD=$PWD
64
65 CLEANUP=${CLEANUP:-:}
66 SETUP=${SETUP:-:}
67 TRACE=${TRACE:-""}
68 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
69 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
70 . $LUSTRE/tests/test-framework.sh
71 init_test_env $@
72 . ${CONFIG:=$LUSTRE/tests/cfg/${NAME}.sh}
73 get_lustre_env
74 init_logging
75
76 #                                  5          12          (min)"
77 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
78
79 if [ "$mds1_FSTYPE" = "zfs" ]; then
80         # bug number for skipped test: LU-1957
81         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  180"
82         #                                               13    (min)"
83         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
84 fi
85
86 # Get the SLES distro version
87 #
88 # Returns a version string that should only be used in comparing
89 # strings returned by version_code()
90 sles_version_code()
91 {
92         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
93
94         # All SuSE Linux versions have one decimal. version_code expects two
95         local sles_version=$version.0
96         version_code $sles_version
97 }
98
99 # Check if we are running on Ubuntu or SLES so we can make decisions on
100 # what tests to run
101 if [ -r /etc/SuSE-release ]; then
102         sles_version=$(sles_version_code)
103         [ $sles_version -lt $(version_code 11.4.0) ] &&
104                 # bug number for skipped test: LU-4341
105                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
106         [ $sles_version -lt $(version_code 12.0.0) ] &&
107                 # bug number for skipped test: LU-3703
108                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
109 elif [ -r /etc/os-release ]; then
110         if grep -qi ubuntu /etc/os-release; then
111                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
112                                                 -e 's/^VERSION=//p' \
113                                                 /etc/os-release |
114                                                 awk '{ print $1 }'))
115
116                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
117                         # bug number for skipped test:
118                         #                LU-10334 LU-10366
119                         ALWAYS_EXCEPT+=" 103a     410"
120                 fi
121         fi
122 fi
123
124 FAIL_ON_ERROR=false
125
126 cleanup() {
127         echo -n "cln.."
128         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
129         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
130 }
131 setup() {
132         echo -n "mnt.."
133         load_modules
134         setupall || exit 10
135         echo "done"
136 }
137
138 check_swap_layouts_support()
139 {
140         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
141                 skip "Does not support layout lock."
142 }
143
144 check_and_setup_lustre
145 DIR=${DIR:-$MOUNT}
146 assert_DIR
147
148 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
149
150 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
151 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
152 rm -rf $DIR/[Rdfs][0-9]*
153
154 # $RUNAS_ID may get set incorrectly somewhere else
155 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
156         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
157
158 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
159
160 build_test_filter
161
162 if [ "${ONLY}" = "MOUNT" ] ; then
163         echo "Lustre is up, please go on"
164         exit
165 fi
166
167 echo "preparing for tests involving mounts"
168 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
169 touch $EXT2_DEV
170 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
171 echo # add a newline after mke2fs.
172
173 umask 077
174
175 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
176 lctl set_param debug=-1 2> /dev/null || true
177 test_0a() {
178         touch $DIR/$tfile
179         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
180         rm $DIR/$tfile
181         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
182 }
183 run_test 0a "touch; rm ====================="
184
185 test_0b() {
186         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
187         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
188 }
189 run_test 0b "chmod 0755 $DIR ============================="
190
191 test_0c() {
192         $LCTL get_param mdc.*.import | grep "state: FULL" ||
193                 error "import not FULL"
194         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
195                 error "bad target"
196 }
197 run_test 0c "check import proc"
198
199 test_0d() { # LU-3397
200         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
201                 skip "proc exports not supported before 2.10.57"
202
203         local mgs_exp="mgs.MGS.exports"
204         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
205         local exp_client_nid
206         local exp_client_version
207         local exp_val
208         local imp_val
209         local temp_imp=$DIR/$tfile.import
210         local temp_exp=$DIR/$tfile.export
211
212         # save mgc import file to $temp_imp
213         $LCTL get_param mgc.*.import | tee $temp_imp
214         # Check if client uuid is found in MGS export
215         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
216                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
217                         $client_uuid ] &&
218                         break;
219         done
220         # save mgs export file to $temp_exp
221         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
222
223         # Compare the value of field "connect_flags"
224         imp_val=$(grep "connect_flags" $temp_imp)
225         exp_val=$(grep "connect_flags" $temp_exp)
226         [ "$exp_val" == "$imp_val" ] ||
227                 error "export flags '$exp_val' != import flags '$imp_val'"
228
229         # Compare the value of client version
230         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
231         exp_val=$(version_code $exp_client_version)
232         imp_val=$CLIENT_VERSION
233         [ "$exp_val" == "$imp_val" ] ||
234                 error "export client version '$exp_val' != '$imp_val'"
235 }
236 run_test 0d "check export proc ============================="
237
238 test_1() {
239         test_mkdir $DIR/$tdir
240         test_mkdir $DIR/$tdir/d2
241         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
242         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
243         rmdir $DIR/$tdir/d2
244         rmdir $DIR/$tdir
245         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
246 }
247 run_test 1 "mkdir; remkdir; rmdir"
248
249 test_2() {
250         test_mkdir $DIR/$tdir
251         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
252         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
253         rm -r $DIR/$tdir
254         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
255 }
256 run_test 2 "mkdir; touch; rmdir; check file"
257
258 test_3() {
259         test_mkdir $DIR/$tdir
260         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
261         touch $DIR/$tdir/$tfile
262         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
263         rm -r $DIR/$tdir
264         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
265 }
266 run_test 3 "mkdir; touch; rmdir; check dir"
267
268 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
269 test_4() {
270         test_mkdir -i 1 $DIR/$tdir
271
272         touch $DIR/$tdir/$tfile ||
273                 error "Create file under remote directory failed"
274
275         rmdir $DIR/$tdir &&
276                 error "Expect error removing in-use dir $DIR/$tdir"
277
278         test -d $DIR/$tdir || error "Remote directory disappeared"
279
280         rm -rf $DIR/$tdir || error "remove remote dir error"
281 }
282 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
283
284 test_5() {
285         test_mkdir $DIR/$tdir
286         test_mkdir $DIR/$tdir/d2
287         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
288         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
290 }
291 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
292
293 test_6a() {
294         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
295         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
296         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
297                 error "$tfile does not have perm 0666 or UID $UID"
298         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
299         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
300                 error "$tfile should be 0666 and owned by UID $UID"
301 }
302 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
303
304 test_6c() {
305         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
306
307         touch $DIR/$tfile
308         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
309         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
310                 error "$tfile should be owned by UID $RUNAS_ID"
311         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
312         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
313                 error "$tfile should be owned by UID $RUNAS_ID"
314 }
315 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
316
317 test_6e() {
318         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
319
320         touch $DIR/$tfile
321         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
322         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
323                 error "$tfile should be owned by GID $UID"
324         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
325         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
327 }
328 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
329
330 test_6g() {
331         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
332
333         test_mkdir $DIR/$tdir
334         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
335         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
336         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
337         test_mkdir $DIR/$tdir/d/subdir
338         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
339                 error "$tdir/d/subdir should be GID $RUNAS_GID"
340         if [[ $MDSCOUNT -gt 1 ]]; then
341                 # check remote dir sgid inherite
342                 $LFS mkdir -i 0 $DIR/$tdir.local ||
343                         error "mkdir $tdir.local failed"
344                 chmod g+s $DIR/$tdir.local ||
345                         error "chmod $tdir.local failed"
346                 chgrp $RUNAS_GID $DIR/$tdir.local ||
347                         error "chgrp $tdir.local failed"
348                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
349                         error "mkdir $tdir.remote failed"
350                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
351                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
352                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
353                         error "$tdir.remote should be mode 02755"
354         fi
355 }
356 run_test 6g "verify new dir in sgid dir inherits group"
357
358 test_6h() { # bug 7331
359         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
360
361         touch $DIR/$tfile || error "touch failed"
362         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
363         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
364                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
365         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
366                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
367 }
368 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
369
370 test_7a() {
371         test_mkdir $DIR/$tdir
372         $MCREATE $DIR/$tdir/$tfile
373         chmod 0666 $DIR/$tdir/$tfile
374         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
375                 error "$tdir/$tfile should be mode 0666"
376 }
377 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
378
379 test_7b() {
380         if [ ! -d $DIR/$tdir ]; then
381                 test_mkdir $DIR/$tdir
382         fi
383         $MCREATE $DIR/$tdir/$tfile
384         echo -n foo > $DIR/$tdir/$tfile
385         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
386         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
387 }
388 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
389
390 test_8() {
391         test_mkdir $DIR/$tdir
392         touch $DIR/$tdir/$tfile
393         chmod 0666 $DIR/$tdir/$tfile
394         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
395                 error "$tfile mode not 0666"
396 }
397 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
398
399 test_9() {
400         test_mkdir $DIR/$tdir
401         test_mkdir $DIR/$tdir/d2
402         test_mkdir $DIR/$tdir/d2/d3
403         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
404 }
405 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
406
407 test_10() {
408         test_mkdir $DIR/$tdir
409         test_mkdir $DIR/$tdir/d2
410         touch $DIR/$tdir/d2/$tfile
411         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
412                 error "$tdir/d2/$tfile not a file"
413 }
414 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
415
416 test_11() {
417         test_mkdir $DIR/$tdir
418         test_mkdir $DIR/$tdir/d2
419         chmod 0666 $DIR/$tdir/d2
420         chmod 0705 $DIR/$tdir/d2
421         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
422                 error "$tdir/d2 mode not 0705"
423 }
424 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
425
426 test_12() {
427         test_mkdir $DIR/$tdir
428         touch $DIR/$tdir/$tfile
429         chmod 0666 $DIR/$tdir/$tfile
430         chmod 0654 $DIR/$tdir/$tfile
431         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
432                 error "$tdir/d2 mode not 0654"
433 }
434 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
435
436 test_13() {
437         test_mkdir $DIR/$tdir
438         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
439         >  $DIR/$tdir/$tfile
440         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
441                 error "$tdir/$tfile size not 0 after truncate"
442 }
443 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
444
445 test_14() {
446         test_mkdir $DIR/$tdir
447         touch $DIR/$tdir/$tfile
448         rm $DIR/$tdir/$tfile
449         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
450 }
451 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
452
453 test_15() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
457         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
458                 error "$tdir/${tfile_2} not a file after rename"
459         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
460 }
461 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
462
463 test_16() {
464         test_mkdir $DIR/$tdir
465         touch $DIR/$tdir/$tfile
466         rm -rf $DIR/$tdir/$tfile
467         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
468 }
469 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
470
471 test_17a() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
475         ls -l $DIR/$tdir
476         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
477                 error "$tdir/l-exist not a symlink"
478         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
479                 error "$tdir/l-exist not referencing a file"
480         rm -f $DIR/$tdir/l-exist
481         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
482 }
483 run_test 17a "symlinks: create, remove (real)"
484
485 test_17b() {
486         test_mkdir $DIR/$tdir
487         ln -s no-such-file $DIR/$tdir/l-dangle
488         ls -l $DIR/$tdir
489         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
490                 error "$tdir/l-dangle not referencing no-such-file"
491         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
492                 error "$tdir/l-dangle not referencing non-existent file"
493         rm -f $DIR/$tdir/l-dangle
494         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
495 }
496 run_test 17b "symlinks: create, remove (dangling)"
497
498 test_17c() { # bug 3440 - don't save failed open RPC for replay
499         test_mkdir $DIR/$tdir
500         ln -s foo $DIR/$tdir/$tfile
501         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
502 }
503 run_test 17c "symlinks: open dangling (should return error)"
504
505 test_17d() {
506         test_mkdir $DIR/$tdir
507         ln -s foo $DIR/$tdir/$tfile
508         touch $DIR/$tdir/$tfile || error "creating to new symlink"
509 }
510 run_test 17d "symlinks: create dangling"
511
512 test_17e() {
513         test_mkdir $DIR/$tdir
514         local foo=$DIR/$tdir/$tfile
515         ln -s $foo $foo || error "create symlink failed"
516         ls -l $foo || error "ls -l failed"
517         ls $foo && error "ls not failed" || true
518 }
519 run_test 17e "symlinks: create recursive symlink (should return error)"
520
521 test_17f() {
522         test_mkdir $DIR/$tdir
523         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
524         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
525         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
526         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
527         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
528         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
529         ls -l  $DIR/$tdir
530 }
531 run_test 17f "symlinks: long and very long symlink name"
532
533 # str_repeat(S, N) generate a string that is string S repeated N times
534 str_repeat() {
535         local s=$1
536         local n=$2
537         local ret=''
538         while [ $((n -= 1)) -ge 0 ]; do
539                 ret=$ret$s
540         done
541         echo $ret
542 }
543
544 # Long symlinks and LU-2241
545 test_17g() {
546         test_mkdir $DIR/$tdir
547         local TESTS="59 60 61 4094 4095"
548
549         # Fix for inode size boundary in 2.1.4
550         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
551                 TESTS="4094 4095"
552
553         # Patch not applied to 2.2 or 2.3 branches
554         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
555         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
556                 TESTS="4094 4095"
557
558         # skip long symlink name for rhel6.5.
559         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
560         grep -q '6.5' /etc/redhat-release &>/dev/null &&
561                 TESTS="59 60 61 4062 4063"
562
563         for i in $TESTS; do
564                 local SYMNAME=$(str_repeat 'x' $i)
565                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
566                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
567         done
568 }
569 run_test 17g "symlinks: really long symlink name and inode boundaries"
570
571 test_17h() { #bug 17378
572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
573         remote_mds_nodsh && skip "remote MDS with nodsh"
574
575         local mdt_idx
576
577         test_mkdir $DIR/$tdir
578         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
579         $LFS setstripe -c -1 $DIR/$tdir
580         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
581         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
582         touch $DIR/$tdir/$tfile || true
583 }
584 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
585
586 test_17i() { #bug 20018
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         remote_mds_nodsh && skip "remote MDS with nodsh"
589
590         local foo=$DIR/$tdir/$tfile
591         local mdt_idx
592
593         test_mkdir -c1 $DIR/$tdir
594         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
595         ln -s $foo $foo || error "create symlink failed"
596 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
597         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
598         ls -l $foo && error "error not detected"
599         return 0
600 }
601 run_test 17i "don't panic on short symlink (should return error)"
602
603 test_17k() { #bug 22301
604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
605         [[ -z "$(which rsync 2>/dev/null)" ]] &&
606                 skip "no rsync command"
607         rsync --help | grep -q xattr ||
608                 skip_env "$(rsync --version | head -n1) does not support xattrs"
609         test_mkdir $DIR/$tdir
610         test_mkdir $DIR/$tdir.new
611         touch $DIR/$tdir/$tfile
612         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
613         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
614                 error "rsync failed with xattrs enabled"
615 }
616 run_test 17k "symlinks: rsync with xattrs enabled"
617
618 test_17l() { # LU-279
619         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
620                 skip "no getfattr command"
621
622         test_mkdir $DIR/$tdir
623         touch $DIR/$tdir/$tfile
624         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
625         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
626                 # -h to not follow symlinks. -m '' to list all the xattrs.
627                 # grep to remove first line: '# file: $path'.
628                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
629                 do
630                         lgetxattr_size_check $path $xattr ||
631                                 error "lgetxattr_size_check $path $xattr failed"
632                 done
633         done
634 }
635 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
636
637 # LU-1540
638 test_17m() {
639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
640         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
641         remote_mds_nodsh && skip "remote MDS with nodsh"
642         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
643         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
644                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
645
646         local short_sym="0123456789"
647         local wdir=$DIR/$tdir
648         local i
649
650         test_mkdir $wdir
651         long_sym=$short_sym
652         # create a long symlink file
653         for ((i = 0; i < 4; ++i)); do
654                 long_sym=${long_sym}${long_sym}
655         done
656
657         echo "create 512 short and long symlink files under $wdir"
658         for ((i = 0; i < 256; ++i)); do
659                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
660                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
661         done
662
663         echo "erase them"
664         rm -f $wdir/*
665         sync
666         wait_delete_completed
667
668         echo "recreate the 512 symlink files with a shorter string"
669         for ((i = 0; i < 512; ++i)); do
670                 # rewrite the symlink file with a shorter string
671                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
672                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
673         done
674
675         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
676         local devname=$(mdsdevname $mds_index)
677
678         echo "stop and checking mds${mds_index}:"
679         # e2fsck should not return error
680         stop mds${mds_index}
681         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
682         rc=$?
683
684         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
685                 error "start mds${mds_index} failed"
686         df $MOUNT > /dev/null 2>&1
687         [ $rc -eq 0 ] ||
688                 error "e2fsck detected error for short/long symlink: rc=$rc"
689         rm -f $wdir/*
690 }
691 run_test 17m "run e2fsck against MDT which contains short/long symlink"
692
693 check_fs_consistency_17n() {
694         local mdt_index
695         local rc=0
696
697         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
698         # so it only check MDT1/MDT2 instead of all of MDTs.
699         for mdt_index in 1 2; do
700                 local devname=$(mdsdevname $mdt_index)
701                 # e2fsck should not return error
702                 stop mds${mdt_index}
703                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
704                         rc=$((rc + $?))
705
706                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
707                         error "mount mds$mdt_index failed"
708                 df $MOUNT > /dev/null 2>&1
709         done
710         return $rc
711 }
712
713 test_17n() {
714         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
716         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
717         remote_mds_nodsh && skip "remote MDS with nodsh"
718         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
719         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
720                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
721
722         local i
723
724         test_mkdir $DIR/$tdir
725         for ((i=0; i<10; i++)); do
726                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
727                         error "create remote dir error $i"
728                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
729                         error "create files under remote dir failed $i"
730         done
731
732         check_fs_consistency_17n ||
733                 error "e2fsck report error after create files under remote dir"
734
735         for ((i = 0; i < 10; i++)); do
736                 rm -rf $DIR/$tdir/remote_dir_${i} ||
737                         error "destroy remote dir error $i"
738         done
739
740         check_fs_consistency_17n ||
741                 error "e2fsck report error after unlink files under remote dir"
742
743         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
744                 skip "lustre < 2.4.50 does not support migrate mv"
745
746         for ((i = 0; i < 10; i++)); do
747                 mkdir -p $DIR/$tdir/remote_dir_${i}
748                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
749                         error "create files under remote dir failed $i"
750                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
751                         error "migrate remote dir error $i"
752         done
753         check_fs_consistency_17n || error "e2fsck report error after migration"
754
755         for ((i = 0; i < 10; i++)); do
756                 rm -rf $DIR/$tdir/remote_dir_${i} ||
757                         error "destroy remote dir error $i"
758         done
759
760         check_fs_consistency_17n || error "e2fsck report error after unlink"
761 }
762 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
763
764 test_17o() {
765         remote_mds_nodsh && skip "remote MDS with nodsh"
766         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
767                 skip "Need MDS version at least 2.3.64"
768
769         local wdir=$DIR/${tdir}o
770         local mdt_index
771         local rc=0
772
773         test_mkdir $wdir
774         touch $wdir/$tfile
775         mdt_index=$($LFS getstripe -m $wdir/$tfile)
776         mdt_index=$((mdt_index + 1))
777
778         cancel_lru_locks mdc
779         #fail mds will wait the failover finish then set
780         #following fail_loc to avoid interfer the recovery process.
781         fail mds${mdt_index}
782
783         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
784         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
785         ls -l $wdir/$tfile && rc=1
786         do_facet mds${mdt_index} lctl set_param fail_loc=0
787         [[ $rc -eq 0 ]] || error "stat file should fail"
788 }
789 run_test 17o "stat file with incompat LMA feature"
790
791 test_18() {
792         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
793         ls $DIR || error "Failed to ls $DIR: $?"
794 }
795 run_test 18 "touch .../f ; ls ... =============================="
796
797 test_19a() {
798         touch $DIR/$tfile
799         ls -l $DIR
800         rm $DIR/$tfile
801         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
802 }
803 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
804
805 test_19b() {
806         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
807 }
808 run_test 19b "ls -l .../f19 (should return error) =============="
809
810 test_19c() {
811         [ $RUNAS_ID -eq $UID ] &&
812                 skip_env "RUNAS_ID = UID = $UID -- skipping"
813
814         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
815 }
816 run_test 19c "$RUNAS touch .../f19 (should return error) =="
817
818 test_19d() {
819         cat $DIR/f19 && error || true
820 }
821 run_test 19d "cat .../f19 (should return error) =============="
822
823 test_20() {
824         touch $DIR/$tfile
825         rm $DIR/$tfile
826         touch $DIR/$tfile
827         rm $DIR/$tfile
828         touch $DIR/$tfile
829         rm $DIR/$tfile
830         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
831 }
832 run_test 20 "touch .../f ; ls -l ..."
833
834 test_21() {
835         test_mkdir $DIR/$tdir
836         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
837         ln -s dangle $DIR/$tdir/link
838         echo foo >> $DIR/$tdir/link
839         cat $DIR/$tdir/dangle
840         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
841         $CHECKSTAT -f -t file $DIR/$tdir/link ||
842                 error "$tdir/link not linked to a file"
843 }
844 run_test 21 "write to dangling link"
845
846 test_22() {
847         local wdir=$DIR/$tdir
848         test_mkdir $wdir
849         chown $RUNAS_ID:$RUNAS_GID $wdir
850         (cd $wdir || error "cd $wdir failed";
851                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
852                 $RUNAS tar xf -)
853         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
854         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
855         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
856                 error "checkstat -u failed"
857 }
858 run_test 22 "unpack tar archive as non-root user"
859
860 # was test_23
861 test_23a() {
862         test_mkdir $DIR/$tdir
863         local file=$DIR/$tdir/$tfile
864
865         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
866         openfile -f O_CREAT:O_EXCL $file &&
867                 error "$file recreate succeeded" || true
868 }
869 run_test 23a "O_CREAT|O_EXCL in subdir"
870
871 test_23b() { # bug 18988
872         test_mkdir $DIR/$tdir
873         local file=$DIR/$tdir/$tfile
874
875         rm -f $file
876         echo foo > $file || error "write filed"
877         echo bar >> $file || error "append filed"
878         $CHECKSTAT -s 8 $file || error "wrong size"
879         rm $file
880 }
881 run_test 23b "O_APPEND check"
882
883 # LU-9409, size with O_APPEND and tiny writes
884 test_23c() {
885         local file=$DIR/$tfile
886
887         # single dd
888         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
889         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
890         rm -f $file
891
892         # racing tiny writes
893         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
894         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
895         wait
896         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
897         rm -f $file
898
899         #racing tiny & normal writes
900         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
901         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
902         wait
903         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
904         rm -f $file
905
906         #racing tiny & normal writes 2, ugly numbers
907         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
908         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
909         wait
910         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
911         rm -f $file
912 }
913 run_test 23c "O_APPEND size checks for tiny writes"
914
915 # LU-11069 file offset is correct after appending writes
916 test_23d() {
917         local file=$DIR/$tfile
918         local offset
919
920         echo CentaurHauls > $file
921         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
922         if ((offset != 26)); then
923                 error "wrong offset, expected 26, got '$offset'"
924         fi
925 }
926 run_test 23d "file offset is correct after appending writes"
927
928 # rename sanity
929 test_24a() {
930         echo '-- same directory rename'
931         test_mkdir $DIR/$tdir
932         touch $DIR/$tdir/$tfile.1
933         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
934         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
935 }
936 run_test 24a "rename file to non-existent target"
937
938 test_24b() {
939         test_mkdir $DIR/$tdir
940         touch $DIR/$tdir/$tfile.{1,2}
941         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
942         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
943         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
944 }
945 run_test 24b "rename file to existing target"
946
947 test_24c() {
948         test_mkdir $DIR/$tdir
949         test_mkdir $DIR/$tdir/d$testnum.1
950         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
951         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
952         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
953 }
954 run_test 24c "rename directory to non-existent target"
955
956 test_24d() {
957         test_mkdir -c1 $DIR/$tdir
958         test_mkdir -c1 $DIR/$tdir/d$testnum.1
959         test_mkdir -c1 $DIR/$tdir/d$testnum.2
960         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
961         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
962         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
963 }
964 run_test 24d "rename directory to existing target"
965
966 test_24e() {
967         echo '-- cross directory renames --'
968         test_mkdir $DIR/R5a
969         test_mkdir $DIR/R5b
970         touch $DIR/R5a/f
971         mv $DIR/R5a/f $DIR/R5b/g
972         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
973         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
974 }
975 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
976
977 test_24f() {
978         test_mkdir $DIR/R6a
979         test_mkdir $DIR/R6b
980         touch $DIR/R6a/f $DIR/R6b/g
981         mv $DIR/R6a/f $DIR/R6b/g
982         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
983         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
984 }
985 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
986
987 test_24g() {
988         test_mkdir $DIR/R7a
989         test_mkdir $DIR/R7b
990         test_mkdir $DIR/R7a/d
991         mv $DIR/R7a/d $DIR/R7b/e
992         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
993         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
994 }
995 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
996
997 test_24h() {
998         test_mkdir -c1 $DIR/R8a
999         test_mkdir -c1 $DIR/R8b
1000         test_mkdir -c1 $DIR/R8a/d
1001         test_mkdir -c1 $DIR/R8b/e
1002         mrename $DIR/R8a/d $DIR/R8b/e
1003         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1004         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1005 }
1006 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1007
1008 test_24i() {
1009         echo "-- rename error cases"
1010         test_mkdir $DIR/R9
1011         test_mkdir $DIR/R9/a
1012         touch $DIR/R9/f
1013         mrename $DIR/R9/f $DIR/R9/a
1014         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1015         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1016         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1017 }
1018 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1019
1020 test_24j() {
1021         test_mkdir $DIR/R10
1022         mrename $DIR/R10/f $DIR/R10/g
1023         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1024         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1025         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1026 }
1027 run_test 24j "source does not exist ============================"
1028
1029 test_24k() {
1030         test_mkdir $DIR/R11a
1031         test_mkdir $DIR/R11a/d
1032         touch $DIR/R11a/f
1033         mv $DIR/R11a/f $DIR/R11a/d
1034         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1035         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1036 }
1037 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1038
1039 # bug 2429 - rename foo foo foo creates invalid file
1040 test_24l() {
1041         f="$DIR/f24l"
1042         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1043 }
1044 run_test 24l "Renaming a file to itself ========================"
1045
1046 test_24m() {
1047         f="$DIR/f24m"
1048         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1049         # on ext3 this does not remove either the source or target files
1050         # though the "expected" operation would be to remove the source
1051         $CHECKSTAT -t file ${f} || error "${f} missing"
1052         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1053 }
1054 run_test 24m "Renaming a file to a hard link to itself ========="
1055
1056 test_24n() {
1057     f="$DIR/f24n"
1058     # this stats the old file after it was renamed, so it should fail
1059     touch ${f}
1060     $CHECKSTAT ${f} || error "${f} missing"
1061     mv ${f} ${f}.rename
1062     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1063     $CHECKSTAT -a ${f} || error "${f} exists"
1064 }
1065 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1066
1067 test_24o() {
1068         test_mkdir $DIR/$tdir
1069         rename_many -s random -v -n 10 $DIR/$tdir
1070 }
1071 run_test 24o "rename of files during htree split"
1072
1073 test_24p() {
1074         test_mkdir $DIR/R12a
1075         test_mkdir $DIR/R12b
1076         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1077         mrename $DIR/R12a $DIR/R12b
1078         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1079         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1080         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1081         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1082 }
1083 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1084
1085 cleanup_multiop_pause() {
1086         trap 0
1087         kill -USR1 $MULTIPID
1088 }
1089
1090 test_24q() {
1091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1092
1093         test_mkdir $DIR/R13a
1094         test_mkdir $DIR/R13b
1095         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1096         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1097         MULTIPID=$!
1098
1099         trap cleanup_multiop_pause EXIT
1100         mrename $DIR/R13a $DIR/R13b
1101         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1102         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1103         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1104         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1105         cleanup_multiop_pause
1106         wait $MULTIPID || error "multiop close failed"
1107 }
1108 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1109
1110 test_24r() { #bug 3789
1111         test_mkdir $DIR/R14a
1112         test_mkdir $DIR/R14a/b
1113         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1114         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1115         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1116 }
1117 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1118
1119 test_24s() {
1120         test_mkdir $DIR/R15a
1121         test_mkdir $DIR/R15a/b
1122         test_mkdir $DIR/R15a/b/c
1123         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1124         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1125         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1126 }
1127 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1128 test_24t() {
1129         test_mkdir $DIR/R16a
1130         test_mkdir $DIR/R16a/b
1131         test_mkdir $DIR/R16a/b/c
1132         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1133         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1134         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1135 }
1136 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1137
1138 test_24u() { # bug12192
1139         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1140         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1141 }
1142 run_test 24u "create stripe file"
1143
1144 simple_cleanup_common() {
1145         local rc=0
1146         trap 0
1147         [ -z "$DIR" -o -z "$tdir" ] && return 0
1148
1149         local start=$SECONDS
1150         rm -rf $DIR/$tdir
1151         rc=$?
1152         wait_delete_completed
1153         echo "cleanup time $((SECONDS - start))"
1154         return $rc
1155 }
1156
1157 max_pages_per_rpc() {
1158         local mdtname="$(printf "MDT%04x" ${1:-0})"
1159         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1160 }
1161
1162 test_24v() {
1163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1164
1165         local nrfiles=${COUNT:-100000}
1166         local fname="$DIR/$tdir/$tfile"
1167
1168         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1169         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1170
1171         test_mkdir "$(dirname $fname)"
1172         # assume MDT0000 has the fewest inodes
1173         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1174         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1175         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1176
1177         trap simple_cleanup_common EXIT
1178
1179         createmany -m "$fname" $nrfiles
1180
1181         cancel_lru_locks mdc
1182         lctl set_param mdc.*.stats clear
1183
1184         # was previously test_24D: LU-6101
1185         # readdir() returns correct number of entries after cursor reload
1186         local num_ls=$(ls $DIR/$tdir | wc -l)
1187         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1188         local num_all=$(ls -a $DIR/$tdir | wc -l)
1189         if [ $num_ls -ne $nrfiles -o $num_uniq -ne $nrfiles -o \
1190              $num_all -ne $((nrfiles + 2)) ]; then
1191                 error "Expected $nrfiles files, got $num_ls " \
1192                         "($num_uniq unique $num_all .&..)"
1193         fi
1194         # LU-5 large readdir
1195         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1196         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1197         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1198         # take into account of overhead in lu_dirpage header and end mark in
1199         # each page, plus one in rpc_num calculation.
1200         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1201         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1202         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1203         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1204         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1205         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1206         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1207         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1208                 error "large readdir doesn't take effect: " \
1209                       "$mds_readpage should be about $rpc_max"
1210
1211         simple_cleanup_common
1212 }
1213 run_test 24v "list large directory (test hash collision, b=17560)"
1214
1215 test_24w() { # bug21506
1216         SZ1=234852
1217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1218         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1219         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1220         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1221         [[ "$SZ1" -eq "$SZ2" ]] ||
1222                 error "Error reading at the end of the file $tfile"
1223 }
1224 run_test 24w "Reading a file larger than 4Gb"
1225
1226 test_24x() {
1227         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1229         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1230                 skip "Need MDS version at least 2.7.56"
1231
1232         local MDTIDX=1
1233         local remote_dir=$DIR/$tdir/remote_dir
1234
1235         test_mkdir $DIR/$tdir
1236         $LFS mkdir -i $MDTIDX $remote_dir ||
1237                 error "create remote directory failed"
1238
1239         test_mkdir $DIR/$tdir/src_dir
1240         touch $DIR/$tdir/src_file
1241         test_mkdir $remote_dir/tgt_dir
1242         touch $remote_dir/tgt_file
1243
1244         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1245                 error "rename dir cross MDT failed!"
1246
1247         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1248                 error "rename file cross MDT failed!"
1249
1250         touch $DIR/$tdir/ln_file
1251         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1252                 error "ln file cross MDT failed"
1253
1254         rm -rf $DIR/$tdir || error "Can not delete directories"
1255 }
1256 run_test 24x "cross MDT rename/link"
1257
1258 test_24y() {
1259         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1261
1262         local remote_dir=$DIR/$tdir/remote_dir
1263         local mdtidx=1
1264
1265         test_mkdir $DIR/$tdir
1266         $LFS mkdir -i $mdtidx $remote_dir ||
1267                 error "create remote directory failed"
1268
1269         test_mkdir $remote_dir/src_dir
1270         touch $remote_dir/src_file
1271         test_mkdir $remote_dir/tgt_dir
1272         touch $remote_dir/tgt_file
1273
1274         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1275                 error "rename subdir in the same remote dir failed!"
1276
1277         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1278                 error "rename files in the same remote dir failed!"
1279
1280         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1281                 error "link files in the same remote dir failed!"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24y "rename/link on the same dir should succeed"
1286
1287 test_24A() { # LU-3182
1288         local NFILES=5000
1289
1290         rm -rf $DIR/$tdir
1291         test_mkdir $DIR/$tdir
1292         trap simple_cleanup_common EXIT
1293         createmany -m $DIR/$tdir/$tfile $NFILES
1294         local t=$(ls $DIR/$tdir | wc -l)
1295         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1296         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1297         if [ $t -ne $NFILES -o $u -ne $NFILES -o $v -ne $((NFILES + 2)) ] ; then
1298                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1299         fi
1300
1301         simple_cleanup_common || error "Can not delete directories"
1302 }
1303 run_test 24A "readdir() returns correct number of entries."
1304
1305 test_24B() { # LU-4805
1306         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1307
1308         local count
1309
1310         test_mkdir $DIR/$tdir
1311         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1312                 error "create striped dir failed"
1313
1314         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1315         [ $count -eq 2 ] || error "Expected 2, got $count"
1316
1317         touch $DIR/$tdir/striped_dir/a
1318
1319         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1320         [ $count -eq 3 ] || error "Expected 3, got $count"
1321
1322         touch $DIR/$tdir/striped_dir/.f
1323
1324         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1325         [ $count -eq 4 ] || error "Expected 4, got $count"
1326
1327         rm -rf $DIR/$tdir || error "Can not delete directories"
1328 }
1329 run_test 24B "readdir for striped dir return correct number of entries"
1330
1331 test_24C() {
1332         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1333
1334         mkdir $DIR/$tdir
1335         mkdir $DIR/$tdir/d0
1336         mkdir $DIR/$tdir/d1
1337
1338         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1339                 error "create striped dir failed"
1340
1341         cd $DIR/$tdir/d0/striped_dir
1342
1343         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1344         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1345         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1346
1347         [ "$d0_ino" = "$parent_ino" ] ||
1348                 error ".. wrong, expect $d0_ino, get $parent_ino"
1349
1350         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1351                 error "mv striped dir failed"
1352
1353         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1354
1355         [ "$d1_ino" = "$parent_ino" ] ||
1356                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1357 }
1358 run_test 24C "check .. in striped dir"
1359
1360 test_24E() {
1361         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1363
1364         mkdir -p $DIR/$tdir
1365         mkdir $DIR/$tdir/src_dir
1366         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1367                 error "create remote source failed"
1368
1369         touch $DIR/$tdir/src_dir/src_child/a
1370
1371         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1372                 error "create remote target dir failed"
1373
1374         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1375                 error "create remote target child failed"
1376
1377         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1378                 error "rename dir cross MDT failed!"
1379
1380         find $DIR/$tdir
1381
1382         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1383                 error "src_child still exists after rename"
1384
1385         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1386                 error "missing file(a) after rename"
1387
1388         rm -rf $DIR/$tdir || error "Can not delete directories"
1389 }
1390 run_test 24E "cross MDT rename/link"
1391
1392 test_24F () {
1393         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1394
1395         local repeats=1000
1396         [ "$SLOW" = "no" ] && repeats=100
1397
1398         mkdir -p $DIR/$tdir
1399
1400         echo "$repeats repeats"
1401         for ((i = 0; i < repeats; i++)); do
1402                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1403                 touch $DIR/$tdir/test/a || error "touch fails"
1404                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1405                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1406         done
1407
1408         true
1409 }
1410 run_test 24F "hash order vs readdir (LU-11330)"
1411
1412 test_25a() {
1413         echo '== symlink sanity ============================================='
1414
1415         test_mkdir $DIR/d25
1416         ln -s d25 $DIR/s25
1417         touch $DIR/s25/foo ||
1418                 error "File creation in symlinked directory failed"
1419 }
1420 run_test 25a "create file in symlinked directory ==============="
1421
1422 test_25b() {
1423         [ ! -d $DIR/d25 ] && test_25a
1424         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1425 }
1426 run_test 25b "lookup file in symlinked directory ==============="
1427
1428 test_26a() {
1429         test_mkdir $DIR/d26
1430         test_mkdir $DIR/d26/d26-2
1431         ln -s d26/d26-2 $DIR/s26
1432         touch $DIR/s26/foo || error "File creation failed"
1433 }
1434 run_test 26a "multiple component symlink ======================="
1435
1436 test_26b() {
1437         test_mkdir -p $DIR/$tdir/d26-2
1438         ln -s $tdir/d26-2/foo $DIR/s26-2
1439         touch $DIR/s26-2 || error "File creation failed"
1440 }
1441 run_test 26b "multiple component symlink at end of lookup ======"
1442
1443 test_26c() {
1444         test_mkdir $DIR/d26.2
1445         touch $DIR/d26.2/foo
1446         ln -s d26.2 $DIR/s26.2-1
1447         ln -s s26.2-1 $DIR/s26.2-2
1448         ln -s s26.2-2 $DIR/s26.2-3
1449         chmod 0666 $DIR/s26.2-3/foo
1450 }
1451 run_test 26c "chain of symlinks"
1452
1453 # recursive symlinks (bug 439)
1454 test_26d() {
1455         ln -s d26-3/foo $DIR/d26-3
1456 }
1457 run_test 26d "create multiple component recursive symlink"
1458
1459 test_26e() {
1460         [ ! -h $DIR/d26-3 ] && test_26d
1461         rm $DIR/d26-3
1462 }
1463 run_test 26e "unlink multiple component recursive symlink"
1464
1465 # recursive symlinks (bug 7022)
1466 test_26f() {
1467         test_mkdir $DIR/$tdir
1468         test_mkdir $DIR/$tdir/$tfile
1469         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1470         test_mkdir -p lndir/bar1
1471         test_mkdir $DIR/$tdir/$tfile/$tfile
1472         cd $tfile                || error "cd $tfile failed"
1473         ln -s .. dotdot          || error "ln dotdot failed"
1474         ln -s dotdot/lndir lndir || error "ln lndir failed"
1475         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1476         output=`ls $tfile/$tfile/lndir/bar1`
1477         [ "$output" = bar1 ] && error "unexpected output"
1478         rm -r $tfile             || error "rm $tfile failed"
1479         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1480 }
1481 run_test 26f "rm -r of a directory which has recursive symlink"
1482
1483 test_27a() {
1484         test_mkdir $DIR/$tdir
1485         $LFS getstripe $DIR/$tdir
1486         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1487         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1488         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1489 }
1490 run_test 27a "one stripe file"
1491
1492 test_27b() {
1493         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1494
1495         test_mkdir $DIR/$tdir
1496         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1497         $LFS getstripe -c $DIR/$tdir/$tfile
1498         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1499                 error "two-stripe file doesn't have two stripes"
1500
1501         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1502 }
1503 run_test 27b "create and write to two stripe file"
1504
1505 test_27d() {
1506         test_mkdir $DIR/$tdir
1507         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1508                 error "setstripe failed"
1509         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1510         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1511 }
1512 run_test 27d "create file with default settings"
1513
1514 test_27e() {
1515         # LU-5839 adds check for existed layout before setting it
1516         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1517                 skip "Need MDS version at least 2.7.56"
1518
1519         test_mkdir $DIR/$tdir
1520         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1521         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1522         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1523 }
1524 run_test 27e "setstripe existing file (should return error)"
1525
1526 test_27f() {
1527         test_mkdir $DIR/$tdir
1528         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1529                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1530         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1531                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1532         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1533         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1534 }
1535 run_test 27f "setstripe with bad stripe size (should return error)"
1536
1537 test_27g() {
1538         test_mkdir $DIR/$tdir
1539         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1540         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1541                 error "$DIR/$tdir/$tfile has object"
1542 }
1543 run_test 27g "$LFS getstripe with no objects"
1544
1545 test_27i() {
1546         test_mkdir $DIR/$tdir
1547         touch $DIR/$tdir/$tfile || error "touch failed"
1548         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1549                 error "missing objects"
1550 }
1551 run_test 27i "$LFS getstripe with some objects"
1552
1553 test_27j() {
1554         test_mkdir $DIR/$tdir
1555         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1556                 error "setstripe failed" || true
1557 }
1558 run_test 27j "setstripe with bad stripe offset (should return error)"
1559
1560 test_27k() { # bug 2844
1561         test_mkdir $DIR/$tdir
1562         local file=$DIR/$tdir/$tfile
1563         local ll_max_blksize=$((4 * 1024 * 1024))
1564         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1565         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1566         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1567         dd if=/dev/zero of=$file bs=4k count=1
1568         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1569         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1570 }
1571 run_test 27k "limit i_blksize for broken user apps"
1572
1573 test_27l() {
1574         mcreate $DIR/$tfile || error "creating file"
1575         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1576                 error "setstripe should have failed" || true
1577 }
1578 run_test 27l "check setstripe permissions (should return error)"
1579
1580 test_27m() {
1581         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1582
1583         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1584                    head -n1)
1585         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1586                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1587         fi
1588         trap simple_cleanup_common EXIT
1589         test_mkdir $DIR/$tdir
1590         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1591         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1592                 error "dd should fill OST0"
1593         i=2
1594         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1595                 i=$((i + 1))
1596                 [ $i -gt 256 ] && break
1597         done
1598         i=$((i + 1))
1599         touch $DIR/$tdir/$tfile.$i
1600         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1601             awk '{print $1}'| grep -w "0") ] &&
1602                 error "OST0 was full but new created file still use it"
1603         i=$((i + 1))
1604         touch $DIR/$tdir/$tfile.$i
1605         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1606             awk '{print $1}'| grep -w "0") ] &&
1607                 error "OST0 was full but new created file still use it"
1608         simple_cleanup_common
1609 }
1610 run_test 27m "create file while OST0 was full"
1611
1612 sleep_maxage() {
1613         local delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1614                       awk '{ print $1 * 2; exit; }')
1615         sleep $delay
1616 }
1617
1618 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1619 # if the OST isn't full anymore.
1620 reset_enospc() {
1621         local OSTIDX=${1:-""}
1622
1623         local list=$(comma_list $(osts_nodes))
1624         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1625
1626         do_nodes $list lctl set_param fail_loc=0
1627         sync    # initiate all OST_DESTROYs from MDS to OST
1628         sleep_maxage
1629 }
1630
1631 exhaust_precreations() {
1632         local OSTIDX=$1
1633         local FAILLOC=$2
1634         local FAILIDX=${3:-$OSTIDX}
1635         local ofacet=ost$((OSTIDX + 1))
1636
1637         test_mkdir -p -c1 $DIR/$tdir
1638         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1639         local mfacet=mds$((mdtidx + 1))
1640         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1641
1642         local OST=$(ostname_from_index $OSTIDX)
1643
1644         # on the mdt's osc
1645         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1646         local last_id=$(do_facet $mfacet lctl get_param -n \
1647                         osc.$mdtosc_proc1.prealloc_last_id)
1648         local next_id=$(do_facet $mfacet lctl get_param -n \
1649                         osc.$mdtosc_proc1.prealloc_next_id)
1650
1651         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1652         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1653
1654         test_mkdir -p $DIR/$tdir/${OST}
1655         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1656 #define OBD_FAIL_OST_ENOSPC              0x215
1657         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1658         echo "Creating to objid $last_id on ost $OST..."
1659         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1660         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1661         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1662         sleep_maxage
1663 }
1664
1665 exhaust_all_precreations() {
1666         local i
1667         for (( i=0; i < OSTCOUNT; i++ )) ; do
1668                 exhaust_precreations $i $1 -1
1669         done
1670 }
1671
1672 test_27n() {
1673         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1675         remote_mds_nodsh && skip "remote MDS with nodsh"
1676         remote_ost_nodsh && skip "remote OST with nodsh"
1677
1678         reset_enospc
1679         rm -f $DIR/$tdir/$tfile
1680         exhaust_precreations 0 0x80000215
1681         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1682         touch $DIR/$tdir/$tfile || error "touch failed"
1683         $LFS getstripe $DIR/$tdir/$tfile
1684         reset_enospc
1685 }
1686 run_test 27n "create file with some full OSTs"
1687
1688 test_27o() {
1689         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1691         remote_mds_nodsh && skip "remote MDS with nodsh"
1692         remote_ost_nodsh && skip "remote OST with nodsh"
1693
1694         reset_enospc
1695         rm -f $DIR/$tdir/$tfile
1696         exhaust_all_precreations 0x215
1697
1698         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1699
1700         reset_enospc
1701         rm -rf $DIR/$tdir/*
1702 }
1703 run_test 27o "create file with all full OSTs (should error)"
1704
1705 test_27p() {
1706         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1708         remote_mds_nodsh && skip "remote MDS with nodsh"
1709         remote_ost_nodsh && skip "remote OST with nodsh"
1710
1711         reset_enospc
1712         rm -f $DIR/$tdir/$tfile
1713         test_mkdir $DIR/$tdir
1714
1715         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1716         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1717         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1718
1719         exhaust_precreations 0 0x80000215
1720         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1721         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1722         $LFS getstripe $DIR/$tdir/$tfile
1723
1724         reset_enospc
1725 }
1726 run_test 27p "append to a truncated file with some full OSTs"
1727
1728 test_27q() {
1729         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1731         remote_mds_nodsh && skip "remote MDS with nodsh"
1732         remote_ost_nodsh && skip "remote OST with nodsh"
1733
1734         reset_enospc
1735         rm -f $DIR/$tdir/$tfile
1736
1737         test_mkdir $DIR/$tdir
1738         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1739         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1740                 error "truncate $DIR/$tdir/$tfile failed"
1741         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1742
1743         exhaust_all_precreations 0x215
1744
1745         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1746         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1747
1748         reset_enospc
1749 }
1750 run_test 27q "append to truncated file with all OSTs full (should error)"
1751
1752 test_27r() {
1753         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1755         remote_mds_nodsh && skip "remote MDS with nodsh"
1756         remote_ost_nodsh && skip "remote OST with nodsh"
1757
1758         reset_enospc
1759         rm -f $DIR/$tdir/$tfile
1760         exhaust_precreations 0 0x80000215
1761
1762         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1763
1764         reset_enospc
1765 }
1766 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1767
1768 test_27s() { # bug 10725
1769         test_mkdir $DIR/$tdir
1770         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1771         local stripe_count=0
1772         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1773         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1774                 error "stripe width >= 2^32 succeeded" || true
1775
1776 }
1777 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1778
1779 test_27t() { # bug 10864
1780         WDIR=$(pwd)
1781         WLFS=$(which lfs)
1782         cd $DIR
1783         touch $tfile
1784         $WLFS getstripe $tfile
1785         cd $WDIR
1786 }
1787 run_test 27t "check that utils parse path correctly"
1788
1789 test_27u() { # bug 4900
1790         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1791         remote_mds_nodsh && skip "remote MDS with nodsh"
1792
1793         local index
1794         local list=$(comma_list $(mdts_nodes))
1795
1796 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1797         do_nodes $list $LCTL set_param fail_loc=0x139
1798         test_mkdir -p $DIR/$tdir
1799         trap simple_cleanup_common EXIT
1800         createmany -o $DIR/$tdir/t- 1000
1801         do_nodes $list $LCTL set_param fail_loc=0
1802
1803         TLOG=$TMP/$tfile.getstripe
1804         $LFS getstripe $DIR/$tdir > $TLOG
1805         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1806         unlinkmany $DIR/$tdir/t- 1000
1807         trap 0
1808         [[ $OBJS -gt 0 ]] &&
1809                 error "$OBJS objects created on OST-0. See $TLOG" ||
1810                 rm -f $TLOG
1811 }
1812 run_test 27u "skip object creation on OSC w/o objects"
1813
1814 test_27v() { # bug 4900
1815         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1817         remote_mds_nodsh && skip "remote MDS with nodsh"
1818         remote_ost_nodsh && skip "remote OST with nodsh"
1819
1820         exhaust_all_precreations 0x215
1821         reset_enospc
1822
1823         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1824
1825         touch $DIR/$tdir/$tfile
1826         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1827         # all except ost1
1828         for (( i=1; i < OSTCOUNT; i++ )); do
1829                 do_facet ost$i lctl set_param fail_loc=0x705
1830         done
1831         local START=`date +%s`
1832         createmany -o $DIR/$tdir/$tfile 32
1833
1834         local FINISH=`date +%s`
1835         local TIMEOUT=`lctl get_param -n timeout`
1836         local PROCESS=$((FINISH - START))
1837         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1838                error "$FINISH - $START >= $TIMEOUT / 2"
1839         sleep $((TIMEOUT / 2 - PROCESS))
1840         reset_enospc
1841 }
1842 run_test 27v "skip object creation on slow OST"
1843
1844 test_27w() { # bug 10997
1845         test_mkdir $DIR/$tdir
1846         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1847         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1848                 error "stripe size $size != 65536" || true
1849         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1850                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1851 }
1852 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1853
1854 test_27wa() {
1855         [[ $OSTCOUNT -lt 2 ]] &&
1856                 skip_env "skipping multiple stripe count/offset test"
1857
1858         test_mkdir $DIR/$tdir
1859         for i in $(seq 1 $OSTCOUNT); do
1860                 offset=$((i - 1))
1861                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1862                         error "setstripe -c $i -i $offset failed"
1863                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1864                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1865                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1866                 [ $index -ne $offset ] &&
1867                         error "stripe offset $index != $offset" || true
1868         done
1869 }
1870 run_test 27wa "check $LFS setstripe -c -i options"
1871
1872 test_27x() {
1873         remote_ost_nodsh && skip "remote OST with nodsh"
1874         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1876
1877         OFFSET=$(($OSTCOUNT - 1))
1878         OSTIDX=0
1879         local OST=$(ostname_from_index $OSTIDX)
1880
1881         test_mkdir $DIR/$tdir
1882         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
1883         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
1884         sleep_maxage
1885         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
1886         for i in $(seq 0 $OFFSET); do
1887                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
1888                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
1889                 error "OST0 was degraded but new created file still use it"
1890         done
1891         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
1892 }
1893 run_test 27x "create files while OST0 is degraded"
1894
1895 test_27y() {
1896         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1897         remote_mds_nodsh && skip "remote MDS with nodsh"
1898         remote_ost_nodsh && skip "remote OST with nodsh"
1899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1900
1901         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
1902         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
1903                 osc.$mdtosc.prealloc_last_id)
1904         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
1905                 osc.$mdtosc.prealloc_next_id)
1906         local fcount=$((last_id - next_id))
1907         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
1908         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
1909
1910         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
1911                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
1912         local OST_DEACTIVE_IDX=-1
1913         local OSC
1914         local OSTIDX
1915         local OST
1916
1917         for OSC in $MDS_OSCS; do
1918                 OST=$(osc_to_ost $OSC)
1919                 OSTIDX=$(index_from_ostuuid $OST)
1920                 if [ $OST_DEACTIVE_IDX == -1 ]; then
1921                         OST_DEACTIVE_IDX=$OSTIDX
1922                 fi
1923                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
1924                         echo $OSC "is Deactivated:"
1925                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
1926                 fi
1927         done
1928
1929         OSTIDX=$(index_from_ostuuid $OST)
1930         test_mkdir $DIR/$tdir
1931         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
1932
1933         for OSC in $MDS_OSCS; do
1934                 OST=$(osc_to_ost $OSC)
1935                 OSTIDX=$(index_from_ostuuid $OST)
1936                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1937                         echo $OST "is degraded:"
1938                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1939                                                 obdfilter.$OST.degraded=1
1940                 fi
1941         done
1942
1943         sleep_maxage
1944         createmany -o $DIR/$tdir/$tfile $fcount
1945
1946         for OSC in $MDS_OSCS; do
1947                 OST=$(osc_to_ost $OSC)
1948                 OSTIDX=$(index_from_ostuuid $OST)
1949                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1950                         echo $OST "is recovered from degraded:"
1951                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1952                                                 obdfilter.$OST.degraded=0
1953                 else
1954                         do_facet $SINGLEMDS lctl --device %$OSC activate
1955                 fi
1956         done
1957
1958         # all osp devices get activated, hence -1 stripe count restored
1959         local stripe_count=0
1960
1961         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
1962         # devices get activated.
1963         sleep_maxage
1964         $LFS setstripe -c -1 $DIR/$tfile
1965         stripe_count=$($LFS getstripe -c $DIR/$tfile)
1966         rm -f $DIR/$tfile
1967         [ $stripe_count -ne $OSTCOUNT ] &&
1968                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
1969         return 0
1970 }
1971 run_test 27y "create files while OST0 is degraded and the rest inactive"
1972
1973 check_seq_oid()
1974 {
1975         log "check file $1"
1976
1977         lmm_count=$($LFS getstripe -c $1)
1978         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
1979         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
1980
1981         local old_ifs="$IFS"
1982         IFS=$'[:]'
1983         fid=($($LFS path2fid $1))
1984         IFS="$old_ifs"
1985
1986         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
1987         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
1988
1989         # compare lmm_seq and lu_fid->f_seq
1990         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
1991         # compare lmm_object_id and lu_fid->oid
1992         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
1993
1994         # check the trusted.fid attribute of the OST objects of the file
1995         local have_obdidx=false
1996         local stripe_nr=0
1997         $LFS getstripe $1 | while read obdidx oid hex seq; do
1998                 # skip lines up to and including "obdidx"
1999                 [ -z "$obdidx" ] && break
2000                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2001                 $have_obdidx || continue
2002
2003                 local ost=$((obdidx + 1))
2004                 local dev=$(ostdevname $ost)
2005                 local oid_hex
2006
2007                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2008
2009                 seq=$(echo $seq | sed -e "s/^0x//g")
2010                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2011                         oid_hex=$(echo $oid)
2012                 else
2013                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2014                 fi
2015                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2016
2017                 local ff=""
2018                 #
2019                 # Don't unmount/remount the OSTs if we don't need to do that.
2020                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2021                 # update too, until that use mount/ll_decode_filter_fid/mount.
2022                 # Re-enable when debugfs will understand new filter_fid.
2023                 #
2024                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2025                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2026                                 $dev 2>/dev/null" | grep "parent=")
2027                 fi
2028                 if [ -z "$ff" ]; then
2029                         stop ost$ost
2030                         mount_fstype ost$ost
2031                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2032                                 $(facet_mntpt ost$ost)/$obj_file)
2033                         unmount_fstype ost$ost
2034                         start ost$ost $dev $OST_MOUNT_OPTS
2035                         clients_up
2036                 fi
2037
2038                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2039
2040                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2041
2042                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2043                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2044                 #
2045                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2046                 #       stripe_size=1048576 component_id=1 component_start=0 \
2047                 #       component_end=33554432
2048                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2049                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2050                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2051                 local ff_pstripe
2052                 if grep -q 'stripe=' <<<$ff; then
2053                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2054                 else
2055                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2056                         # into f_ver in this case.  See comment on ff_parent.
2057                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2058                 fi
2059
2060                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2061                 [ $ff_pseq = $lmm_seq ] ||
2062                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2063                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2064                 [ $ff_poid = $lmm_oid ] ||
2065                         error "FF parent OID $ff_poid != $lmm_oid"
2066                 (($ff_pstripe == $stripe_nr)) ||
2067                         error "FF stripe $ff_pstripe != $stripe_nr"
2068
2069                 stripe_nr=$((stripe_nr + 1))
2070                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2071                         continue
2072                 if grep -q 'stripe_count=' <<<$ff; then
2073                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2074                                             -e 's/ .*//' <<<$ff)
2075                         [ $lmm_count = $ff_scnt ] ||
2076                                 error "FF stripe count $lmm_count != $ff_scnt"
2077                 fi
2078         done
2079 }
2080
2081 test_27z() {
2082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2083         remote_ost_nodsh && skip "remote OST with nodsh"
2084
2085         test_mkdir $DIR/$tdir
2086         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2087                 { error "setstripe -c -1 failed"; return 1; }
2088         # We need to send a write to every object to get parent FID info set.
2089         # This _should_ also work for setattr, but does not currently.
2090         # touch $DIR/$tdir/$tfile-1 ||
2091         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2092                 { error "dd $tfile-1 failed"; return 2; }
2093         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2094                 { error "setstripe -c -1 failed"; return 3; }
2095         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2096                 { error "dd $tfile-2 failed"; return 4; }
2097
2098         # make sure write RPCs have been sent to OSTs
2099         sync; sleep 5; sync
2100
2101         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2102         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2103 }
2104 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2105
2106 test_27A() { # b=19102
2107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2108
2109         save_layout_restore_at_exit $MOUNT
2110         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2111         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2112                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2113         local default_size=$($LFS getstripe -S $MOUNT)
2114         local default_offset=$($LFS getstripe -i $MOUNT)
2115         local dsize=$(do_facet $SINGLEMDS \
2116                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2117         [ $default_size -eq $dsize ] ||
2118                 error "stripe size $default_size != $dsize"
2119         [ $default_offset -eq -1 ] ||
2120                 error "stripe offset $default_offset != -1"
2121 }
2122 run_test 27A "check filesystem-wide default LOV EA values"
2123
2124 test_27B() { # LU-2523
2125         test_mkdir $DIR/$tdir
2126         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2127         touch $DIR/$tdir/f0
2128         # open f1 with O_LOV_DELAY_CREATE
2129         # rename f0 onto f1
2130         # call setstripe ioctl on open file descriptor for f1
2131         # close
2132         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2133                 $DIR/$tdir/f0
2134
2135         rm -f $DIR/$tdir/f1
2136         # open f1 with O_LOV_DELAY_CREATE
2137         # unlink f1
2138         # call setstripe ioctl on open file descriptor for f1
2139         # close
2140         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2141
2142         # Allow multiop to fail in imitation of NFS's busted semantics.
2143         true
2144 }
2145 run_test 27B "call setstripe on open unlinked file/rename victim"
2146
2147 test_27C() { #LU-2871
2148         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2149
2150         declare -a ost_idx
2151         local index
2152         local found
2153         local i
2154         local j
2155
2156         test_mkdir $DIR/$tdir
2157         cd $DIR/$tdir
2158         for i in $(seq 0 $((OSTCOUNT - 1))); do
2159                 # set stripe across all OSTs starting from OST$i
2160                 $LFS setstripe -i $i -c -1 $tfile$i
2161                 # get striping information
2162                 ost_idx=($($LFS getstripe $tfile$i |
2163                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2164                 echo ${ost_idx[@]}
2165
2166                 # check the layout
2167                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2168                         error "${#ost_idx[@]} != $OSTCOUNT"
2169
2170                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2171                         found=0
2172                         for j in $(echo ${ost_idx[@]}); do
2173                                 if [ $index -eq $j ]; then
2174                                         found=1
2175                                         break
2176                                 fi
2177                         done
2178                         [ $found = 1 ] ||
2179                                 error "Can not find $index in ${ost_idx[@]}"
2180                 done
2181         done
2182 }
2183 run_test 27C "check full striping across all OSTs"
2184
2185 test_27D() {
2186         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2187         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2188         remote_mds_nodsh && skip "remote MDS with nodsh"
2189
2190         local POOL=${POOL:-testpool}
2191         local first_ost=0
2192         local last_ost=$(($OSTCOUNT - 1))
2193         local ost_step=1
2194         local ost_list=$(seq $first_ost $ost_step $last_ost)
2195         local ost_range="$first_ost $last_ost $ost_step"
2196
2197         if ! combined_mgs_mds ; then
2198                 mount_mgs_client
2199         fi
2200
2201         test_mkdir $DIR/$tdir
2202         pool_add $POOL || error "pool_add failed"
2203         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2204
2205         local skip27D
2206         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2207                 skip27D+="-s 29"
2208         [ $MDS1_VERSION -lt $(version_code 2.9.55) -o \
2209           $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2210                 skip27D+=" -s 30,31"
2211         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2212                 error "llapi_layout_test failed"
2213
2214         destroy_test_pools || error "destroy test pools failed"
2215
2216         if ! combined_mgs_mds ; then
2217                 umount_mgs_client
2218         fi
2219 }
2220 run_test 27D "validate llapi_layout API"
2221
2222 # Verify that default_easize is increased from its initial value after
2223 # accessing a widely striped file.
2224 test_27E() {
2225         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2226         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2227                 skip "client does not have LU-3338 fix"
2228
2229         # 72 bytes is the minimum space required to store striping
2230         # information for a file striped across one OST:
2231         # (sizeof(struct lov_user_md_v3) +
2232         #  sizeof(struct lov_user_ost_data_v1))
2233         local min_easize=72
2234         $LCTL set_param -n llite.*.default_easize $min_easize ||
2235                 error "lctl set_param failed"
2236         local easize=$($LCTL get_param -n llite.*.default_easize)
2237
2238         [ $easize -eq $min_easize ] ||
2239                 error "failed to set default_easize"
2240
2241         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2242                 error "setstripe failed"
2243         cat $DIR/$tfile
2244         rm $DIR/$tfile
2245
2246         easize=$($LCTL get_param -n llite.*.default_easize)
2247
2248         [ $easize -gt $min_easize ] ||
2249                 error "default_easize not updated"
2250 }
2251 run_test 27E "check that default extended attribute size properly increases"
2252
2253 test_27F() { # LU-5346/LU-7975
2254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2255         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2256         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2257                 skip "Need MDS version at least 2.8.51"
2258         remote_ost_nodsh && skip "remote OST with nodsh"
2259
2260         test_mkdir $DIR/$tdir
2261         rm -f $DIR/$tdir/f0
2262         $LFS setstripe -c 2 $DIR/$tdir
2263
2264         # stop all OSTs to reproduce situation for LU-7975 ticket
2265         for num in $(seq $OSTCOUNT); do
2266                 stop ost$num
2267         done
2268
2269         # open/create f0 with O_LOV_DELAY_CREATE
2270         # truncate f0 to a non-0 size
2271         # close
2272         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2273
2274         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2275         # open/write it again to force delayed layout creation
2276         cat /etc/hosts > $DIR/$tdir/f0 &
2277         catpid=$!
2278
2279         # restart OSTs
2280         for num in $(seq $OSTCOUNT); do
2281                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2282                         error "ost$num failed to start"
2283         done
2284
2285         wait $catpid || error "cat failed"
2286
2287         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2288         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2289                 error "wrong stripecount"
2290
2291 }
2292 run_test 27F "Client resend delayed layout creation with non-zero size"
2293
2294 test_27G() { #LU-10629
2295         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2296                 skip "Need MDS version at least 2.11.51"
2297         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2298         remote_mds_nodsh && skip "remote MDS with nodsh"
2299         local POOL=${POOL:-testpool}
2300         local ostrange="0 0 1"
2301
2302         test_mkdir $DIR/$tdir
2303         pool_add $POOL || error "pool_add failed"
2304         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2305         $LFS setstripe -p $POOL $DIR/$tdir
2306
2307         local pool=$($LFS getstripe -p $DIR/$tdir)
2308
2309         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2310
2311         $LFS setstripe -d $DIR/$tdir
2312
2313         pool=$($LFS getstripe -p $DIR/$tdir)
2314
2315         rmdir $DIR/$tdir
2316
2317         [ -z "$pool" ] || error "'$pool' is not empty"
2318 }
2319 run_test 27G "Clear OST pool from stripe"
2320
2321 test_27H() {
2322         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2323                 skip "Need MDS version newer than 2.11.54"
2324         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2325         test_mkdir $DIR/$tdir
2326         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2327         touch $DIR/$tdir/$tfile
2328         $LFS getstripe -c $DIR/$tdir/$tfile
2329         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2330                 error "two-stripe file doesn't have two stripes"
2331
2332         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2333         $LFS getstripe -y $DIR/$tdir/$tfile
2334         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2335              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2336                 error "expected l_ost_idx: [02]$ not matched"
2337
2338         # make sure ost list has been cleared
2339         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2340         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2341                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2342         touch $DIR/$tdir/f3
2343         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2344 }
2345 run_test 27H "Set specific OSTs stripe"
2346
2347 # createtest also checks that device nodes are created and
2348 # then visible correctly (#2091)
2349 test_28() { # bug 2091
2350         test_mkdir $DIR/d28
2351         $CREATETEST $DIR/d28/ct || error "createtest failed"
2352 }
2353 run_test 28 "create/mknod/mkdir with bad file types ============"
2354
2355 test_29() {
2356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2357
2358         sync; sleep 1; sync # flush out any dirty pages from previous tests
2359         cancel_lru_locks
2360         test_mkdir $DIR/d29
2361         touch $DIR/d29/foo
2362         log 'first d29'
2363         ls -l $DIR/d29
2364
2365         declare -i LOCKCOUNTORIG=0
2366         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2367                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2368         done
2369         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2370
2371         declare -i LOCKUNUSEDCOUNTORIG=0
2372         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2373                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2374         done
2375
2376         log 'second d29'
2377         ls -l $DIR/d29
2378         log 'done'
2379
2380         declare -i LOCKCOUNTCURRENT=0
2381         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2382                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2383         done
2384
2385         declare -i LOCKUNUSEDCOUNTCURRENT=0
2386         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2387                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2388         done
2389
2390         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2391                 $LCTL set_param -n ldlm.dump_namespaces ""
2392                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2393                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2394                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2395                 return 2
2396         fi
2397         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2398                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2399                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2400                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2401                 return 3
2402         fi
2403 }
2404 run_test 29 "IT_GETATTR regression  ============================"
2405
2406 test_30a() { # was test_30
2407         cp $(which ls) $DIR || cp /bin/ls $DIR
2408         $DIR/ls / || error "Can't execute binary from lustre"
2409         rm $DIR/ls
2410 }
2411 run_test 30a "execute binary from Lustre (execve) =============="
2412
2413 test_30b() {
2414         cp `which ls` $DIR || cp /bin/ls $DIR
2415         chmod go+rx $DIR/ls
2416         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2417         rm $DIR/ls
2418 }
2419 run_test 30b "execute binary from Lustre as non-root ==========="
2420
2421 test_30c() { # b=22376
2422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2423
2424         cp `which ls` $DIR || cp /bin/ls $DIR
2425         chmod a-rw $DIR/ls
2426         cancel_lru_locks mdc
2427         cancel_lru_locks osc
2428         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2429         rm -f $DIR/ls
2430 }
2431 run_test 30c "execute binary from Lustre without read perms ===="
2432
2433 test_31a() {
2434         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2435         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2436 }
2437 run_test 31a "open-unlink file =================================="
2438
2439 test_31b() {
2440         touch $DIR/f31 || error "touch $DIR/f31 failed"
2441         ln $DIR/f31 $DIR/f31b || error "ln failed"
2442         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2443         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2444 }
2445 run_test 31b "unlink file with multiple links while open ======="
2446
2447 test_31c() {
2448         touch $DIR/f31 || error "touch $DIR/f31 failed"
2449         ln $DIR/f31 $DIR/f31c || error "ln failed"
2450         multiop_bg_pause $DIR/f31 O_uc ||
2451                 error "multiop_bg_pause for $DIR/f31 failed"
2452         MULTIPID=$!
2453         $MULTIOP $DIR/f31c Ouc
2454         kill -USR1 $MULTIPID
2455         wait $MULTIPID
2456 }
2457 run_test 31c "open-unlink file with multiple links ============="
2458
2459 test_31d() {
2460         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2461         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2462 }
2463 run_test 31d "remove of open directory ========================="
2464
2465 test_31e() { # bug 2904
2466         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2467 }
2468 run_test 31e "remove of open non-empty directory ==============="
2469
2470 test_31f() { # bug 4554
2471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2472
2473         set -vx
2474         test_mkdir $DIR/d31f
2475         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2476         cp /etc/hosts $DIR/d31f
2477         ls -l $DIR/d31f
2478         $LFS getstripe $DIR/d31f/hosts
2479         multiop_bg_pause $DIR/d31f D_c || return 1
2480         MULTIPID=$!
2481
2482         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2483         test_mkdir $DIR/d31f
2484         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2485         cp /etc/hosts $DIR/d31f
2486         ls -l $DIR/d31f
2487         $LFS getstripe $DIR/d31f/hosts
2488         multiop_bg_pause $DIR/d31f D_c || return 1
2489         MULTIPID2=$!
2490
2491         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2492         wait $MULTIPID || error "first opendir $MULTIPID failed"
2493
2494         sleep 6
2495
2496         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2497         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2498         set +vx
2499 }
2500 run_test 31f "remove of open directory with open-unlink file ==="
2501
2502 test_31g() {
2503         echo "-- cross directory link --"
2504         test_mkdir -c1 $DIR/${tdir}ga
2505         test_mkdir -c1 $DIR/${tdir}gb
2506         touch $DIR/${tdir}ga/f
2507         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2508         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2509         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2510         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2511         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2512 }
2513 run_test 31g "cross directory link==============="
2514
2515 test_31h() {
2516         echo "-- cross directory link --"
2517         test_mkdir -c1 $DIR/${tdir}
2518         test_mkdir -c1 $DIR/${tdir}/dir
2519         touch $DIR/${tdir}/f
2520         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
2521         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
2522         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
2523         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
2524         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
2525 }
2526 run_test 31h "cross directory link under child==============="
2527
2528 test_31i() {
2529         echo "-- cross directory link --"
2530         test_mkdir -c1 $DIR/$tdir
2531         test_mkdir -c1 $DIR/$tdir/dir
2532         touch $DIR/$tdir/dir/f
2533         ln $DIR/$tdir/dir/f $DIR/$tdir/g
2534         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
2535         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
2536         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
2537         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
2538 }
2539 run_test 31i "cross directory link under parent==============="
2540
2541 test_31j() {
2542         test_mkdir -c1 -p $DIR/$tdir
2543         test_mkdir -c1 -p $DIR/$tdir/dir1
2544         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
2545         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
2546         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
2547         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
2548         return 0
2549 }
2550 run_test 31j "link for directory==============="
2551
2552 test_31k() {
2553         test_mkdir -c1 -p $DIR/$tdir
2554         touch $DIR/$tdir/s
2555         touch $DIR/$tdir/exist
2556         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
2557         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
2558         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
2559         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
2560         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
2561         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
2562         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
2563         return 0
2564 }
2565 run_test 31k "link to file: the same, non-existing, dir==============="
2566
2567 test_31m() {
2568         mkdir $DIR/d31m
2569         touch $DIR/d31m/s
2570         mkdir $DIR/d31m2
2571         touch $DIR/d31m2/exist
2572         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
2573         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
2574         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
2575         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
2576         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
2577         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
2578         return 0
2579 }
2580 run_test 31m "link to file: the same, non-existing, dir==============="
2581
2582 test_31n() {
2583         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
2584         nlink=$(stat --format=%h $DIR/$tfile)
2585         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2586         local fd=$(free_fd)
2587         local cmd="exec $fd<$DIR/$tfile"
2588         eval $cmd
2589         cmd="exec $fd<&-"
2590         trap "eval $cmd" EXIT
2591         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2592         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2593         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
2594         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2595         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
2596         eval $cmd
2597 }
2598 run_test 31n "check link count of unlinked file"
2599
2600 link_one() {
2601         local TEMPNAME=$(mktemp $1_XXXXXX)
2602         mlink $TEMPNAME $1 2> /dev/null &&
2603                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
2604         munlink $TEMPNAME
2605 }
2606
2607 test_31o() { # LU-2901
2608         test_mkdir $DIR/$tdir
2609         for LOOP in $(seq 100); do
2610                 rm -f $DIR/$tdir/$tfile*
2611                 for THREAD in $(seq 8); do
2612                         link_one $DIR/$tdir/$tfile.$LOOP &
2613                 done
2614                 wait
2615                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
2616                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
2617                         error "$LINKS duplicate links to $tfile.$LOOP" &&
2618                         break || true
2619         done
2620 }
2621 run_test 31o "duplicate hard links with same filename"
2622
2623 test_31p() {
2624         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
2625
2626         test_mkdir $DIR/$tdir
2627         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
2628         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
2629
2630         opendirunlink $DIR/$tdir/striped_dir/test1 ||
2631                 error "open unlink test1 failed"
2632         opendirunlink $DIR/$tdir/striped_dir/test2 ||
2633                 error "open unlink test2 failed"
2634
2635         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
2636                 error "test1 still exists"
2637         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
2638                 error "test2 still exists"
2639 }
2640 run_test 31p "remove of open striped directory"
2641
2642 cleanup_test32_mount() {
2643         local rc=0
2644         trap 0
2645         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
2646         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
2647         losetup -d $loopdev || true
2648         rm -rf $DIR/$tdir
2649         return $rc
2650 }
2651
2652 test_32a() {
2653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2654
2655         echo "== more mountpoints and symlinks ================="
2656         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2657         trap cleanup_test32_mount EXIT
2658         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2659         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2660                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2661         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
2662                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
2663         cleanup_test32_mount
2664 }
2665 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
2666
2667 test_32b() {
2668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2669
2670         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2671         trap cleanup_test32_mount EXIT
2672         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2673         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2674                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2675         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
2676                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
2677         cleanup_test32_mount
2678 }
2679 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
2680
2681 test_32c() {
2682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2683
2684         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2685         trap cleanup_test32_mount EXIT
2686         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2687         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2688                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2689         test_mkdir -p $DIR/$tdir/d2/test_dir
2690         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2691                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
2692         cleanup_test32_mount
2693 }
2694 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
2695
2696 test_32d() {
2697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2698
2699         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2700         trap cleanup_test32_mount EXIT
2701         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2702         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2703                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2704         test_mkdir -p $DIR/$tdir/d2/test_dir
2705         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2706                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
2707         cleanup_test32_mount
2708 }
2709 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
2710
2711 test_32e() {
2712         rm -fr $DIR/$tdir
2713         test_mkdir -p $DIR/$tdir/tmp
2714         local tmp_dir=$DIR/$tdir/tmp
2715         ln -s $DIR/$tdir $tmp_dir/symlink11
2716         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2717         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
2718         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
2719 }
2720 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
2721
2722 test_32f() {
2723         rm -fr $DIR/$tdir
2724         test_mkdir -p $DIR/$tdir/tmp
2725         local tmp_dir=$DIR/$tdir/tmp
2726         ln -s $DIR/$tdir $tmp_dir/symlink11
2727         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2728         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
2729         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
2730 }
2731 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
2732
2733 test_32g() {
2734         local tmp_dir=$DIR/$tdir/tmp
2735         test_mkdir -p $tmp_dir
2736         test_mkdir $DIR/${tdir}2
2737         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2738         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2739         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
2740         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
2741         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
2742         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
2743 }
2744 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2745
2746 test_32h() {
2747         rm -fr $DIR/$tdir $DIR/${tdir}2
2748         tmp_dir=$DIR/$tdir/tmp
2749         test_mkdir -p $tmp_dir
2750         test_mkdir $DIR/${tdir}2
2751         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2752         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2753         ls $tmp_dir/symlink12 || error "listing symlink12"
2754         ls $DIR/$tdir/symlink02  || error "listing symlink02"
2755 }
2756 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2757
2758 test_32i() {
2759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2760
2761         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2762         trap cleanup_test32_mount EXIT
2763         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2764         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2765                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2766         touch $DIR/$tdir/test_file
2767         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
2768                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
2769         cleanup_test32_mount
2770 }
2771 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
2772
2773 test_32j() {
2774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2775
2776         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2777         trap cleanup_test32_mount EXIT
2778         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2779         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2780                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2781         touch $DIR/$tdir/test_file
2782         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
2783                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
2784         cleanup_test32_mount
2785 }
2786 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
2787
2788 test_32k() {
2789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2790
2791         rm -fr $DIR/$tdir
2792         trap cleanup_test32_mount EXIT
2793         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2794         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2795                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2796         test_mkdir -p $DIR/$tdir/d2
2797         touch $DIR/$tdir/d2/test_file || error "touch failed"
2798         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2799                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
2800         cleanup_test32_mount
2801 }
2802 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
2803
2804 test_32l() {
2805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2806
2807         rm -fr $DIR/$tdir
2808         trap cleanup_test32_mount EXIT
2809         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2810         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2811                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2812         test_mkdir -p $DIR/$tdir/d2
2813         touch $DIR/$tdir/d2/test_file || error "touch failed"
2814         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2815                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
2816         cleanup_test32_mount
2817 }
2818 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
2819
2820 test_32m() {
2821         rm -fr $DIR/d32m
2822         test_mkdir -p $DIR/d32m/tmp
2823         TMP_DIR=$DIR/d32m/tmp
2824         ln -s $DIR $TMP_DIR/symlink11
2825         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2826         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
2827                 error "symlink11 not a link"
2828         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
2829                 error "symlink01 not a link"
2830 }
2831 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
2832
2833 test_32n() {
2834         rm -fr $DIR/d32n
2835         test_mkdir -p $DIR/d32n/tmp
2836         TMP_DIR=$DIR/d32n/tmp
2837         ln -s $DIR $TMP_DIR/symlink11
2838         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2839         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
2840         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
2841 }
2842 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
2843
2844 test_32o() {
2845         touch $DIR/$tfile
2846         test_mkdir -p $DIR/d32o/tmp
2847         TMP_DIR=$DIR/d32o/tmp
2848         ln -s $DIR/$tfile $TMP_DIR/symlink12
2849         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2850         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
2851                 error "symlink12 not a link"
2852         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
2853         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
2854                 error "$DIR/d32o/tmp/symlink12 not file type"
2855         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
2856                 error "$DIR/d32o/symlink02 not file type"
2857 }
2858 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
2859
2860 test_32p() {
2861         log 32p_1
2862         rm -fr $DIR/d32p
2863         log 32p_2
2864         rm -f $DIR/$tfile
2865         log 32p_3
2866         touch $DIR/$tfile
2867         log 32p_4
2868         test_mkdir -p $DIR/d32p/tmp
2869         log 32p_5
2870         TMP_DIR=$DIR/d32p/tmp
2871         log 32p_6
2872         ln -s $DIR/$tfile $TMP_DIR/symlink12
2873         log 32p_7
2874         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2875         log 32p_8
2876         cat $DIR/d32p/tmp/symlink12 ||
2877                 error "Can't open $DIR/d32p/tmp/symlink12"
2878         log 32p_9
2879         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
2880         log 32p_10
2881 }
2882 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
2883
2884 test_32q() {
2885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2886
2887         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2888         trap cleanup_test32_mount EXIT
2889         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2890         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2891         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2892                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2893         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
2894         cleanup_test32_mount
2895 }
2896 run_test 32q "stat follows mountpoints in Lustre (should return error)"
2897
2898 test_32r() {
2899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2900
2901         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2902         trap cleanup_test32_mount EXIT
2903         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2904         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2905         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2906                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2907         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
2908         cleanup_test32_mount
2909 }
2910 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
2911
2912 test_33aa() {
2913         rm -f $DIR/$tfile
2914         touch $DIR/$tfile
2915         chmod 444 $DIR/$tfile
2916         chown $RUNAS_ID $DIR/$tfile
2917         log 33_1
2918         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
2919         log 33_2
2920 }
2921 run_test 33aa "write file with mode 444 (should return error)"
2922
2923 test_33a() {
2924         rm -fr $DIR/$tdir
2925         test_mkdir $DIR/$tdir
2926         chown $RUNAS_ID $DIR/$tdir
2927         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
2928                 error "$RUNAS create $tdir/$tfile failed"
2929         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
2930                 error "open RDWR" || true
2931 }
2932 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
2933
2934 test_33b() {
2935         rm -fr $DIR/$tdir
2936         test_mkdir $DIR/$tdir
2937         chown $RUNAS_ID $DIR/$tdir
2938         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
2939 }
2940 run_test 33b "test open file with malformed flags (No panic)"
2941
2942 test_33c() {
2943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2944         remote_ost_nodsh && skip "remote OST with nodsh"
2945
2946         local ostnum
2947         local ostname
2948         local write_bytes
2949         local all_zeros
2950
2951         all_zeros=:
2952         rm -fr $DIR/$tdir
2953         test_mkdir $DIR/$tdir
2954         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
2955
2956         sync
2957         for ostnum in $(seq $OSTCOUNT); do
2958                 # test-framework's OST numbering is one-based, while Lustre's
2959                 # is zero-based
2960                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
2961                 # Parsing llobdstat's output sucks; we could grep the /proc
2962                 # path, but that's likely to not be as portable as using the
2963                 # llobdstat utility.  So we parse lctl output instead.
2964                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
2965                         obdfilter/$ostname/stats |
2966                         awk '/^write_bytes/ {print $7}' )
2967                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
2968                 if (( ${write_bytes:-0} > 0 ))
2969                 then
2970                         all_zeros=false
2971                         break;
2972                 fi
2973         done
2974
2975         $all_zeros || return 0
2976
2977         # Write four bytes
2978         echo foo > $DIR/$tdir/bar
2979         # Really write them
2980         sync
2981
2982         # Total up write_bytes after writing.  We'd better find non-zeros.
2983         for ostnum in $(seq $OSTCOUNT); do
2984                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
2985                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
2986                         obdfilter/$ostname/stats |
2987                         awk '/^write_bytes/ {print $7}' )
2988                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
2989                 if (( ${write_bytes:-0} > 0 ))
2990                 then
2991                         all_zeros=false
2992                         break;
2993                 fi
2994         done
2995
2996         if $all_zeros
2997         then
2998                 for ostnum in $(seq $OSTCOUNT); do
2999                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3000                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3001                         do_facet ost$ostnum lctl get_param -n \
3002                                 obdfilter/$ostname/stats
3003                 done
3004                 error "OST not keeping write_bytes stats (b22312)"
3005         fi
3006 }
3007 run_test 33c "test llobdstat and write_bytes"
3008
3009 test_33d() {
3010         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3012
3013         local MDTIDX=1
3014         local remote_dir=$DIR/$tdir/remote_dir
3015
3016         test_mkdir $DIR/$tdir
3017         $LFS mkdir -i $MDTIDX $remote_dir ||
3018                 error "create remote directory failed"
3019
3020         touch $remote_dir/$tfile
3021         chmod 444 $remote_dir/$tfile
3022         chown $RUNAS_ID $remote_dir/$tfile
3023
3024         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3025
3026         chown $RUNAS_ID $remote_dir
3027         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3028                                         error "create" || true
3029         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3030                                     error "open RDWR" || true
3031         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3032 }
3033 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3034
3035 test_33e() {
3036         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3037
3038         mkdir $DIR/$tdir
3039
3040         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3041         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3042         mkdir $DIR/$tdir/local_dir
3043
3044         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3045         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3046         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3047
3048         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3049                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3050
3051         rmdir $DIR/$tdir/* || error "rmdir failed"
3052
3053         umask 777
3054         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3055         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3056         mkdir $DIR/$tdir/local_dir
3057
3058         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3059         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3060         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3061
3062         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3063                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3064
3065         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3066
3067         umask 000
3068         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3069         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3070         mkdir $DIR/$tdir/local_dir
3071
3072         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3073         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3074         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3075
3076         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3077                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3078 }
3079 run_test 33e "mkdir and striped directory should have same mode"
3080
3081 cleanup_33f() {
3082         trap 0
3083         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3084 }
3085
3086 test_33f() {
3087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3088         remote_mds_nodsh && skip "remote MDS with nodsh"
3089
3090         mkdir $DIR/$tdir
3091         chmod go+rwx $DIR/$tdir
3092         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3093         trap cleanup_33f EXIT
3094
3095         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3096                 error "cannot create striped directory"
3097
3098         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3099                 error "cannot create files in striped directory"
3100
3101         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3102                 error "cannot remove files in striped directory"
3103
3104         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3105                 error "cannot remove striped directory"
3106
3107         cleanup_33f
3108 }
3109 run_test 33f "nonroot user can create, access, and remove a striped directory"
3110
3111 test_33g() {
3112         mkdir -p $DIR/$tdir/dir2
3113
3114         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3115         echo $err
3116         [[ $err =~ "exists" ]] || error "Not exists error"
3117 }
3118 run_test 33g "nonroot user create already existing root created file"
3119
3120 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3121 test_34a() {
3122         rm -f $DIR/f34
3123         $MCREATE $DIR/f34 || error "mcreate failed"
3124         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3125                 error "getstripe failed"
3126         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3127         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3128                 error "getstripe failed"
3129         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3130                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3131 }
3132 run_test 34a "truncate file that has not been opened ==========="
3133
3134 test_34b() {
3135         [ ! -f $DIR/f34 ] && test_34a
3136         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3137                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3138         $OPENFILE -f O_RDONLY $DIR/f34
3139         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3140                 error "getstripe failed"
3141         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3142                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3143 }
3144 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3145
3146 test_34c() {
3147         [ ! -f $DIR/f34 ] && test_34a
3148         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3149                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3150         $OPENFILE -f O_RDWR $DIR/f34
3151         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3152                 error "$LFS getstripe failed"
3153         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3154                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3155 }
3156 run_test 34c "O_RDWR opening file-with-size works =============="
3157
3158 test_34d() {
3159         [ ! -f $DIR/f34 ] && test_34a
3160         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3161                 error "dd failed"
3162         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3163                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3164         rm $DIR/f34
3165 }
3166 run_test 34d "write to sparse file ============================="
3167
3168 test_34e() {
3169         rm -f $DIR/f34e
3170         $MCREATE $DIR/f34e || error "mcreate failed"
3171         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3172         $CHECKSTAT -s 1000 $DIR/f34e ||
3173                 error "Size of $DIR/f34e not equal to 1000 bytes"
3174         $OPENFILE -f O_RDWR $DIR/f34e
3175         $CHECKSTAT -s 1000 $DIR/f34e ||
3176                 error "Size of $DIR/f34e not equal to 1000 bytes"
3177 }
3178 run_test 34e "create objects, some with size and some without =="
3179
3180 test_34f() { # bug 6242, 6243
3181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3182
3183         SIZE34F=48000
3184         rm -f $DIR/f34f
3185         $MCREATE $DIR/f34f || error "mcreate failed"
3186         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3187         dd if=$DIR/f34f of=$TMP/f34f
3188         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3189         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3190         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3191         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3192         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3193 }
3194 run_test 34f "read from a file with no objects until EOF ======="
3195
3196 test_34g() {
3197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3198
3199         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3200                 error "dd failed"
3201         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3202         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3203                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3204         cancel_lru_locks osc
3205         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3206                 error "wrong size after lock cancel"
3207
3208         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3209         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3210                 error "expanding truncate failed"
3211         cancel_lru_locks osc
3212         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3213                 error "wrong expanded size after lock cancel"
3214 }
3215 run_test 34g "truncate long file ==============================="
3216
3217 test_34h() {
3218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3219
3220         local gid=10
3221         local sz=1000
3222
3223         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3224         sync # Flush the cache so that multiop below does not block on cache
3225              # flush when getting the group lock
3226         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3227         MULTIPID=$!
3228
3229         # Since just timed wait is not good enough, let's do a sync write
3230         # that way we are sure enough time for a roundtrip + processing
3231         # passed + 2 seconds of extra margin.
3232         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3233         rm $DIR/${tfile}-1
3234         sleep 2
3235
3236         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3237                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3238                 kill -9 $MULTIPID
3239         fi
3240         wait $MULTIPID
3241         local nsz=`stat -c %s $DIR/$tfile`
3242         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3243 }
3244 run_test 34h "ftruncate file under grouplock should not block"
3245
3246 test_35a() {
3247         cp /bin/sh $DIR/f35a
3248         chmod 444 $DIR/f35a
3249         chown $RUNAS_ID $DIR/f35a
3250         $RUNAS $DIR/f35a && error || true
3251         rm $DIR/f35a
3252 }
3253 run_test 35a "exec file with mode 444 (should return and not leak)"
3254
3255 test_36a() {
3256         rm -f $DIR/f36
3257         utime $DIR/f36 || error "utime failed for MDS"
3258 }
3259 run_test 36a "MDS utime check (mknod, utime)"
3260
3261 test_36b() {
3262         echo "" > $DIR/f36
3263         utime $DIR/f36 || error "utime failed for OST"
3264 }
3265 run_test 36b "OST utime check (open, utime)"
3266
3267 test_36c() {
3268         rm -f $DIR/d36/f36
3269         test_mkdir $DIR/d36
3270         chown $RUNAS_ID $DIR/d36
3271         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3272 }
3273 run_test 36c "non-root MDS utime check (mknod, utime)"
3274
3275 test_36d() {
3276         [ ! -d $DIR/d36 ] && test_36c
3277         echo "" > $DIR/d36/f36
3278         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3279 }
3280 run_test 36d "non-root OST utime check (open, utime)"
3281
3282 test_36e() {
3283         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3284
3285         test_mkdir $DIR/$tdir
3286         touch $DIR/$tdir/$tfile
3287         $RUNAS utime $DIR/$tdir/$tfile &&
3288                 error "utime worked, expected failure" || true
3289 }
3290 run_test 36e "utime on non-owned file (should return error)"
3291
3292 subr_36fh() {
3293         local fl="$1"
3294         local LANG_SAVE=$LANG
3295         local LC_LANG_SAVE=$LC_LANG
3296         export LANG=C LC_LANG=C # for date language
3297
3298         DATESTR="Dec 20  2000"
3299         test_mkdir $DIR/$tdir
3300         lctl set_param fail_loc=$fl
3301         date; date +%s
3302         cp /etc/hosts $DIR/$tdir/$tfile
3303         sync & # write RPC generated with "current" inode timestamp, but delayed
3304         sleep 1
3305         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3306         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3307         cancel_lru_locks $OSC
3308         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3309         date; date +%s
3310         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3311                 echo "BEFORE: $LS_BEFORE" && \
3312                 echo "AFTER : $LS_AFTER" && \
3313                 echo "WANT  : $DATESTR" && \
3314                 error "$DIR/$tdir/$tfile timestamps changed" || true
3315
3316         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3317 }
3318
3319 test_36f() {
3320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3321
3322         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3323         subr_36fh "0x80000214"
3324 }
3325 run_test 36f "utime on file racing with OST BRW write =========="
3326
3327 test_36g() {
3328         remote_ost_nodsh && skip "remote OST with nodsh"
3329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3330         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3331                 skip "Need MDS version at least 2.12.51"
3332
3333         local fmd_max_age
3334         local fmd
3335         local facet="ost1"
3336         local tgt="obdfilter"
3337
3338         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3339
3340         test_mkdir $DIR/$tdir
3341         fmd_max_age=$(do_facet $facet \
3342                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3343                 head -n 1")
3344
3345         echo "FMD max age: ${fmd_max_age}s"
3346         touch $DIR/$tdir/$tfile
3347         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3348                 gawk '{cnt=cnt+$1}  END{print cnt}')
3349         echo "FMD before: $fmd"
3350         [[ $fmd == 0 ]] &&
3351                 error "FMD wasn't create by touch"
3352         sleep $((fmd_max_age + 12))
3353         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3354                 gawk '{cnt=cnt+$1}  END{print cnt}')
3355         echo "FMD after: $fmd"
3356         [[ $fmd == 0 ]] ||
3357                 error "FMD wasn't expired by ping"
3358 }
3359 run_test 36g "FMD cache expiry ====================="
3360
3361 test_36h() {
3362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3363
3364         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3365         subr_36fh "0x80000227"
3366 }
3367 run_test 36h "utime on file racing with OST BRW write =========="
3368
3369 test_36i() {
3370         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3371
3372         test_mkdir $DIR/$tdir
3373         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3374
3375         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3376         local new_mtime=$((mtime + 200))
3377
3378         #change Modify time of striped dir
3379         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3380                         error "change mtime failed"
3381
3382         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3383
3384         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3385 }
3386 run_test 36i "change mtime on striped directory"
3387
3388 # test_37 - duplicate with tests 32q 32r
3389
3390 test_38() {
3391         local file=$DIR/$tfile
3392         touch $file
3393         openfile -f O_DIRECTORY $file
3394         local RC=$?
3395         local ENOTDIR=20
3396         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3397         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3398 }
3399 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3400
3401 test_39a() { # was test_39
3402         touch $DIR/$tfile
3403         touch $DIR/${tfile}2
3404 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3405 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3406 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3407         sleep 2
3408         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3409         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3410                 echo "mtime"
3411                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3412                 echo "atime"
3413                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3414                 echo "ctime"
3415                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3416                 error "O_TRUNC didn't change timestamps"
3417         fi
3418 }
3419 run_test 39a "mtime changed on create"
3420
3421 test_39b() {
3422         test_mkdir -c1 $DIR/$tdir
3423         cp -p /etc/passwd $DIR/$tdir/fopen
3424         cp -p /etc/passwd $DIR/$tdir/flink
3425         cp -p /etc/passwd $DIR/$tdir/funlink
3426         cp -p /etc/passwd $DIR/$tdir/frename
3427         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3428
3429         sleep 1
3430         echo "aaaaaa" >> $DIR/$tdir/fopen
3431         echo "aaaaaa" >> $DIR/$tdir/flink
3432         echo "aaaaaa" >> $DIR/$tdir/funlink
3433         echo "aaaaaa" >> $DIR/$tdir/frename
3434
3435         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3436         local link_new=`stat -c %Y $DIR/$tdir/flink`
3437         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3438         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3439
3440         cat $DIR/$tdir/fopen > /dev/null
3441         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3442         rm -f $DIR/$tdir/funlink2
3443         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3444
3445         for (( i=0; i < 2; i++ )) ; do
3446                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3447                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3448                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3449                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3450
3451                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3452                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3453                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3454                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3455
3456                 cancel_lru_locks $OSC
3457                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3458         done
3459 }
3460 run_test 39b "mtime change on open, link, unlink, rename  ======"
3461
3462 # this should be set to past
3463 TEST_39_MTIME=`date -d "1 year ago" +%s`
3464
3465 # bug 11063
3466 test_39c() {
3467         touch $DIR1/$tfile
3468         sleep 2
3469         local mtime0=`stat -c %Y $DIR1/$tfile`
3470
3471         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3472         local mtime1=`stat -c %Y $DIR1/$tfile`
3473         [ "$mtime1" = $TEST_39_MTIME ] || \
3474                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3475
3476         local d1=`date +%s`
3477         echo hello >> $DIR1/$tfile
3478         local d2=`date +%s`
3479         local mtime2=`stat -c %Y $DIR1/$tfile`
3480         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3481                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3482
3483         mv $DIR1/$tfile $DIR1/$tfile-1
3484
3485         for (( i=0; i < 2; i++ )) ; do
3486                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3487                 [ "$mtime2" = "$mtime3" ] || \
3488                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3489
3490                 cancel_lru_locks $OSC
3491                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3492         done
3493 }
3494 run_test 39c "mtime change on rename ==========================="
3495
3496 # bug 21114
3497 test_39d() {
3498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3499
3500         touch $DIR1/$tfile
3501         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3502
3503         for (( i=0; i < 2; i++ )) ; do
3504                 local mtime=`stat -c %Y $DIR1/$tfile`
3505                 [ $mtime = $TEST_39_MTIME ] || \
3506                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3507
3508                 cancel_lru_locks $OSC
3509                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3510         done
3511 }
3512 run_test 39d "create, utime, stat =============================="
3513
3514 # bug 21114
3515 test_39e() {
3516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3517
3518         touch $DIR1/$tfile
3519         local mtime1=`stat -c %Y $DIR1/$tfile`
3520
3521         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3522
3523         for (( i=0; i < 2; i++ )) ; do
3524                 local mtime2=`stat -c %Y $DIR1/$tfile`
3525                 [ $mtime2 = $TEST_39_MTIME ] || \
3526                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3527
3528                 cancel_lru_locks $OSC
3529                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3530         done
3531 }
3532 run_test 39e "create, stat, utime, stat ========================"
3533
3534 # bug 21114
3535 test_39f() {
3536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3537
3538         touch $DIR1/$tfile
3539         mtime1=`stat -c %Y $DIR1/$tfile`
3540
3541         sleep 2
3542         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3543
3544         for (( i=0; i < 2; i++ )) ; do
3545                 local mtime2=`stat -c %Y $DIR1/$tfile`
3546                 [ $mtime2 = $TEST_39_MTIME ] || \
3547                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3548
3549                 cancel_lru_locks $OSC
3550                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3551         done
3552 }
3553 run_test 39f "create, stat, sleep, utime, stat ================="
3554
3555 # bug 11063
3556 test_39g() {
3557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3558
3559         echo hello >> $DIR1/$tfile
3560         local mtime1=`stat -c %Y $DIR1/$tfile`
3561
3562         sleep 2
3563         chmod o+r $DIR1/$tfile
3564
3565         for (( i=0; i < 2; i++ )) ; do
3566                 local mtime2=`stat -c %Y $DIR1/$tfile`
3567                 [ "$mtime1" = "$mtime2" ] || \
3568                         error "lost mtime: $mtime2, should be $mtime1"
3569
3570                 cancel_lru_locks $OSC
3571                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3572         done
3573 }
3574 run_test 39g "write, chmod, stat ==============================="
3575
3576 # bug 11063
3577 test_39h() {
3578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3579
3580         touch $DIR1/$tfile
3581         sleep 1
3582
3583         local d1=`date`
3584         echo hello >> $DIR1/$tfile
3585         local mtime1=`stat -c %Y $DIR1/$tfile`
3586
3587         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3588         local d2=`date`
3589         if [ "$d1" != "$d2" ]; then
3590                 echo "write and touch not within one second"
3591         else
3592                 for (( i=0; i < 2; i++ )) ; do
3593                         local mtime2=`stat -c %Y $DIR1/$tfile`
3594                         [ "$mtime2" = $TEST_39_MTIME ] || \
3595                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
3596
3597                         cancel_lru_locks $OSC
3598                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3599                 done
3600         fi
3601 }
3602 run_test 39h "write, utime within one second, stat ============="
3603
3604 test_39i() {
3605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3606
3607         touch $DIR1/$tfile
3608         sleep 1
3609
3610         echo hello >> $DIR1/$tfile
3611         local mtime1=`stat -c %Y $DIR1/$tfile`
3612
3613         mv $DIR1/$tfile $DIR1/$tfile-1
3614
3615         for (( i=0; i < 2; i++ )) ; do
3616                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3617
3618                 [ "$mtime1" = "$mtime2" ] || \
3619                         error "lost mtime: $mtime2, should be $mtime1"
3620
3621                 cancel_lru_locks $OSC
3622                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3623         done
3624 }
3625 run_test 39i "write, rename, stat =============================="
3626
3627 test_39j() {
3628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3629
3630         start_full_debug_logging
3631         touch $DIR1/$tfile
3632         sleep 1
3633
3634         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
3635         lctl set_param fail_loc=0x80000412
3636         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
3637                 error "multiop failed"
3638         local multipid=$!
3639         local mtime1=`stat -c %Y $DIR1/$tfile`
3640
3641         mv $DIR1/$tfile $DIR1/$tfile-1
3642
3643         kill -USR1 $multipid
3644         wait $multipid || error "multiop close failed"
3645
3646         for (( i=0; i < 2; i++ )) ; do
3647                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3648                 [ "$mtime1" = "$mtime2" ] ||
3649                         error "mtime is lost on close: $mtime2, " \
3650                               "should be $mtime1"
3651
3652                 cancel_lru_locks $OSC
3653                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3654         done
3655         lctl set_param fail_loc=0
3656         stop_full_debug_logging
3657 }
3658 run_test 39j "write, rename, close, stat ======================="
3659
3660 test_39k() {
3661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3662
3663         touch $DIR1/$tfile
3664         sleep 1
3665
3666         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
3667         local multipid=$!
3668         local mtime1=`stat -c %Y $DIR1/$tfile`
3669
3670         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3671
3672         kill -USR1 $multipid
3673         wait $multipid || error "multiop close failed"
3674
3675         for (( i=0; i < 2; i++ )) ; do
3676                 local mtime2=`stat -c %Y $DIR1/$tfile`
3677
3678                 [ "$mtime2" = $TEST_39_MTIME ] || \
3679                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
3680
3681                 cancel_lru_locks osc
3682                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3683         done
3684 }
3685 run_test 39k "write, utime, close, stat ========================"
3686
3687 # this should be set to future
3688 TEST_39_ATIME=`date -d "1 year" +%s`
3689
3690 test_39l() {
3691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3692         remote_mds_nodsh && skip "remote MDS with nodsh"
3693
3694         local atime_diff=$(do_facet $SINGLEMDS \
3695                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3696         rm -rf $DIR/$tdir
3697         mkdir -p $DIR/$tdir
3698
3699         # test setting directory atime to future
3700         touch -a -d @$TEST_39_ATIME $DIR/$tdir
3701         local atime=$(stat -c %X $DIR/$tdir)
3702         [ "$atime" = $TEST_39_ATIME ] ||
3703                 error "atime is not set to future: $atime, $TEST_39_ATIME"
3704
3705         # test setting directory atime from future to now
3706         local now=$(date +%s)
3707         touch -a -d @$now $DIR/$tdir
3708
3709         atime=$(stat -c %X $DIR/$tdir)
3710         [ "$atime" -eq "$now"  ] ||
3711                 error "atime is not updated from future: $atime, $now"
3712
3713         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
3714         sleep 3
3715
3716         # test setting directory atime when now > dir atime + atime_diff
3717         local d1=$(date +%s)
3718         ls $DIR/$tdir
3719         local d2=$(date +%s)
3720         cancel_lru_locks mdc
3721         atime=$(stat -c %X $DIR/$tdir)
3722         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3723                 error "atime is not updated  : $atime, should be $d2"
3724
3725         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
3726         sleep 3
3727
3728         # test not setting directory atime when now < dir atime + atime_diff
3729         ls $DIR/$tdir
3730         cancel_lru_locks mdc
3731         atime=$(stat -c %X $DIR/$tdir)
3732         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3733                 error "atime is updated to $atime, should remain $d1<atime<$d2"
3734
3735         do_facet $SINGLEMDS \
3736                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3737 }
3738 run_test 39l "directory atime update ==========================="
3739
3740 test_39m() {
3741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3742
3743         touch $DIR1/$tfile
3744         sleep 2
3745         local far_past_mtime=$(date -d "May 29 1953" +%s)
3746         local far_past_atime=$(date -d "Dec 17 1903" +%s)
3747
3748         touch -m -d @$far_past_mtime $DIR1/$tfile
3749         touch -a -d @$far_past_atime $DIR1/$tfile
3750
3751         for (( i=0; i < 2; i++ )) ; do
3752                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
3753                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
3754                         error "atime or mtime set incorrectly"
3755
3756                 cancel_lru_locks $OSC
3757                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3758         done
3759 }
3760 run_test 39m "test atime and mtime before 1970"
3761
3762 test_39n() { # LU-3832
3763         remote_mds_nodsh && skip "remote MDS with nodsh"
3764
3765         local atime_diff=$(do_facet $SINGLEMDS \
3766                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3767         local atime0
3768         local atime1
3769         local atime2
3770
3771         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
3772
3773         rm -rf $DIR/$tfile
3774         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
3775         atime0=$(stat -c %X $DIR/$tfile)
3776
3777         sleep 5
3778         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3779         atime1=$(stat -c %X $DIR/$tfile)
3780
3781         sleep 5
3782         cancel_lru_locks mdc
3783         cancel_lru_locks osc
3784         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3785         atime2=$(stat -c %X $DIR/$tfile)
3786
3787         do_facet $SINGLEMDS \
3788                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3789
3790         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
3791         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
3792 }
3793 run_test 39n "check that O_NOATIME is honored"
3794
3795 test_39o() {
3796         TESTDIR=$DIR/$tdir/$tfile
3797         [ -e $TESTDIR ] && rm -rf $TESTDIR
3798         mkdir -p $TESTDIR
3799         cd $TESTDIR
3800         links1=2
3801         ls
3802         mkdir a b
3803         ls
3804         links2=$(stat -c %h .)
3805         [ $(($links1 + 2)) != $links2 ] &&
3806                 error "wrong links count $(($links1 + 2)) != $links2"
3807         rmdir b
3808         links3=$(stat -c %h .)
3809         [ $(($links1 + 1)) != $links3 ] &&
3810                 error "wrong links count $links1 != $links3"
3811         return 0
3812 }
3813 run_test 39o "directory cached attributes updated after create"
3814
3815 test_39p() {
3816         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3817
3818         local MDTIDX=1
3819         TESTDIR=$DIR/$tdir/$tdir
3820         [ -e $TESTDIR ] && rm -rf $TESTDIR
3821         test_mkdir -p $TESTDIR
3822         cd $TESTDIR
3823         links1=2
3824         ls
3825         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
3826         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
3827         ls
3828         links2=$(stat -c %h .)
3829         [ $(($links1 + 2)) != $links2 ] &&
3830                 error "wrong links count $(($links1 + 2)) != $links2"
3831         rmdir remote_dir2
3832         links3=$(stat -c %h .)
3833         [ $(($links1 + 1)) != $links3 ] &&
3834                 error "wrong links count $links1 != $links3"
3835         return 0
3836 }
3837 run_test 39p "remote directory cached attributes updated after create ========"
3838
3839
3840 test_39q() { # LU-8041
3841         local testdir=$DIR/$tdir
3842         mkdir -p $testdir
3843         multiop_bg_pause $testdir D_c || error "multiop failed"
3844         local multipid=$!
3845         cancel_lru_locks mdc
3846         kill -USR1 $multipid
3847         local atime=$(stat -c %X $testdir)
3848         [ "$atime" -ne 0 ] || error "atime is zero"
3849 }
3850 run_test 39q "close won't zero out atime"
3851
3852 test_40() {
3853         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
3854         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
3855                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
3856         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
3857                 error "$tfile is not 4096 bytes in size"
3858 }
3859 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
3860
3861 test_41() {
3862         # bug 1553
3863         small_write $DIR/f41 18
3864 }
3865 run_test 41 "test small file write + fstat ====================="
3866
3867 count_ost_writes() {
3868         lctl get_param -n ${OSC}.*.stats |
3869                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
3870                         END { printf("%0.0f", writes) }'
3871 }
3872
3873 # decent default
3874 WRITEBACK_SAVE=500
3875 DIRTY_RATIO_SAVE=40
3876 MAX_DIRTY_RATIO=50
3877 BG_DIRTY_RATIO_SAVE=10
3878 MAX_BG_DIRTY_RATIO=25
3879
3880 start_writeback() {
3881         trap 0
3882         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
3883         # dirty_ratio, dirty_background_ratio
3884         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3885                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
3886                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
3887                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
3888         else
3889                 # if file not here, we are a 2.4 kernel
3890                 kill -CONT `pidof kupdated`
3891         fi
3892 }
3893
3894 stop_writeback() {
3895         # setup the trap first, so someone cannot exit the test at the
3896         # exact wrong time and mess up a machine
3897         trap start_writeback EXIT
3898         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
3899         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3900                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
3901                 sysctl -w vm.dirty_writeback_centisecs=0
3902                 sysctl -w vm.dirty_writeback_centisecs=0
3903                 # save and increase /proc/sys/vm/dirty_ratio
3904                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
3905                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
3906                 # save and increase /proc/sys/vm/dirty_background_ratio
3907                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
3908                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
3909         else
3910                 # if file not here, we are a 2.4 kernel
3911                 kill -STOP `pidof kupdated`
3912         fi
3913 }
3914
3915 # ensure that all stripes have some grant before we test client-side cache
3916 setup_test42() {
3917         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
3918                 dd if=/dev/zero of=$i bs=4k count=1
3919                 rm $i
3920         done
3921 }
3922
3923 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
3924 # file truncation, and file removal.
3925 test_42a() {
3926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3927
3928         setup_test42
3929         cancel_lru_locks $OSC
3930         stop_writeback
3931         sync; sleep 1; sync # just to be safe
3932         BEFOREWRITES=`count_ost_writes`
3933         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
3934         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
3935         AFTERWRITES=`count_ost_writes`
3936         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
3937                 error "$BEFOREWRITES < $AFTERWRITES"
3938         start_writeback
3939 }
3940 run_test 42a "ensure that we don't flush on close"
3941
3942 test_42b() {
3943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3944
3945         setup_test42
3946         cancel_lru_locks $OSC
3947         stop_writeback
3948         sync
3949         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
3950         BEFOREWRITES=$(count_ost_writes)
3951         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
3952         AFTERWRITES=$(count_ost_writes)
3953         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
3954                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
3955         fi
3956         BEFOREWRITES=$(count_ost_writes)
3957         sync || error "sync: $?"
3958         AFTERWRITES=$(count_ost_writes)
3959         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
3960                 error "$BEFOREWRITES < $AFTERWRITES on sync"
3961         fi
3962         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
3963         start_writeback
3964         return 0
3965 }
3966 run_test 42b "test destroy of file with cached dirty data ======"
3967
3968 # if these tests just want to test the effect of truncation,
3969 # they have to be very careful.  consider:
3970 # - the first open gets a {0,EOF}PR lock
3971 # - the first write conflicts and gets a {0, count-1}PW
3972 # - the rest of the writes are under {count,EOF}PW
3973 # - the open for truncate tries to match a {0,EOF}PR
3974 #   for the filesize and cancels the PWs.
3975 # any number of fixes (don't get {0,EOF} on open, match
3976 # composite locks, do smarter file size management) fix
3977 # this, but for now we want these tests to verify that
3978 # the cancellation with truncate intent works, so we
3979 # start the file with a full-file pw lock to match against
3980 # until the truncate.
3981 trunc_test() {
3982         test=$1
3983         file=$DIR/$test
3984         offset=$2
3985         cancel_lru_locks $OSC
3986         stop_writeback
3987         # prime the file with 0,EOF PW to match
3988         touch $file
3989         $TRUNCATE $file 0
3990         sync; sync
3991         # now the real test..
3992         dd if=/dev/zero of=$file bs=1024 count=100
3993         BEFOREWRITES=`count_ost_writes`
3994         $TRUNCATE $file $offset
3995         cancel_lru_locks $OSC
3996         AFTERWRITES=`count_ost_writes`
3997         start_writeback
3998 }
3999
4000 test_42c() {
4001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4002
4003         trunc_test 42c 1024
4004         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4005                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4006         rm $file
4007 }
4008 run_test 42c "test partial truncate of file with cached dirty data"
4009
4010 test_42d() {
4011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4012
4013         trunc_test 42d 0
4014         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4015                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4016         rm $file
4017 }
4018 run_test 42d "test complete truncate of file with cached dirty data"
4019
4020 test_42e() { # bug22074
4021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4022
4023         local TDIR=$DIR/${tdir}e
4024         local pages=16 # hardcoded 16 pages, don't change it.
4025         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4026         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4027         local max_dirty_mb
4028         local warmup_files
4029
4030         test_mkdir $DIR/${tdir}e
4031         $LFS setstripe -c 1 $TDIR
4032         createmany -o $TDIR/f $files
4033
4034         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4035
4036         # we assume that with $OSTCOUNT files, at least one of them will
4037         # be allocated on OST0.
4038         warmup_files=$((OSTCOUNT * max_dirty_mb))
4039         createmany -o $TDIR/w $warmup_files
4040
4041         # write a large amount of data into one file and sync, to get good
4042         # avail_grant number from OST.
4043         for ((i=0; i<$warmup_files; i++)); do
4044                 idx=$($LFS getstripe -i $TDIR/w$i)
4045                 [ $idx -ne 0 ] && continue
4046                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4047                 break
4048         done
4049         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4050         sync
4051         $LCTL get_param $proc_osc0/cur_dirty_bytes
4052         $LCTL get_param $proc_osc0/cur_grant_bytes
4053
4054         # create as much dirty pages as we can while not to trigger the actual
4055         # RPCs directly. but depends on the env, VFS may trigger flush during this
4056         # period, hopefully we are good.
4057         for ((i=0; i<$warmup_files; i++)); do
4058                 idx=$($LFS getstripe -i $TDIR/w$i)
4059                 [ $idx -ne 0 ] && continue
4060                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4061         done
4062         $LCTL get_param $proc_osc0/cur_dirty_bytes
4063         $LCTL get_param $proc_osc0/cur_grant_bytes
4064
4065         # perform the real test
4066         $LCTL set_param $proc_osc0/rpc_stats 0
4067         for ((;i<$files; i++)); do
4068                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4069                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4070         done
4071         sync
4072         $LCTL get_param $proc_osc0/rpc_stats
4073
4074         local percent=0
4075         local have_ppr=false
4076         $LCTL get_param $proc_osc0/rpc_stats |
4077                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4078                         # skip lines until we are at the RPC histogram data
4079                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4080                         $have_ppr || continue
4081
4082                         # we only want the percent stat for < 16 pages
4083                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4084
4085                         percent=$((percent + WPCT))
4086                         if [[ $percent -gt 15 ]]; then
4087                                 error "less than 16-pages write RPCs" \
4088                                       "$percent% > 15%"
4089                                 break
4090                         fi
4091                 done
4092         rm -rf $TDIR
4093 }
4094 run_test 42e "verify sub-RPC writes are not done synchronously"
4095
4096 test_43A() { # was test_43
4097         test_mkdir $DIR/$tdir
4098         cp -p /bin/ls $DIR/$tdir/$tfile
4099         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4100         pid=$!
4101         # give multiop a chance to open
4102         sleep 1
4103
4104         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4105         kill -USR1 $pid
4106 }
4107 run_test 43A "execution of file opened for write should return -ETXTBSY"
4108
4109 test_43a() {
4110         test_mkdir $DIR/$tdir
4111         cp -p $(which $MULTIOP) $DIR/$tdir/multiop ||
4112                 cp -p multiop $DIR/$tdir/multiop
4113         MULTIOP_PROG=$DIR/$tdir/multiop multiop_bg_pause $TMP/$tfile.junk O_c ||
4114                 error "multiop open $TMP/$tfile.junk failed"
4115         rm $TMP/$tfile.junk     # delete junk file on close (not part of test)
4116         MULTIOP_PID=$!
4117         $MULTIOP $DIR/$tdir/multiop Oc && error "expected error, got success"
4118         kill -USR1 $MULTIOP_PID || error "kill -USR1 PID $MULTIOP_PID failed"
4119         wait $MULTIOP_PID || error "wait PID $MULTIOP_PID failed"
4120 }
4121 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4122
4123 test_43b() {
4124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4125
4126         test_mkdir $DIR/$tdir
4127         cp -p $(which $MULTIOP) $DIR/$tdir/multiop ||
4128                 cp -p multiop $DIR/$tdir/multiop
4129         MULTIOP_PROG=$DIR/$tdir/multiop multiop_bg_pause $TMP/$tfile.junk O_c ||
4130                 error "multiop open $TMP/$tfile.junk failed"
4131         rm $TMP/$tfile.junk     # delete junk file on close (not part of test)
4132         MULTIOP_PID=$!
4133         $TRUNCATE $DIR/$tdir/multiop 0 && error "expected error, got success"
4134         kill -USR1 $MULTIOP_PID || error "kill -USR1 PID $MULTIOP_PID failed"
4135         wait $MULTIOP_PID || error "wait PID $MULTIOP_PID failed"
4136 }
4137 run_test 43b "truncate of file being executed should return -ETXTBSY"
4138
4139 test_43c() {
4140         local testdir="$DIR/$tdir"
4141         test_mkdir $testdir
4142         cp $SHELL $testdir/
4143         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4144                 ( cd $testdir && md5sum -c )
4145 }
4146 run_test 43c "md5sum of copy into lustre"
4147
4148 test_44A() { # was test_44
4149         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4150
4151         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4152         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4153 }
4154 run_test 44A "zero length read from a sparse stripe"
4155
4156 test_44a() {
4157         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4158                 awk '{ print $2 }')
4159         [ -z "$nstripe" ] && skip "can't get stripe info"
4160         [[ $nstripe -gt $OSTCOUNT ]] &&
4161                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4162
4163         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4164                 awk '{ print $2 }')
4165         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4166                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4167                         awk '{ print $2 }')
4168         fi
4169
4170         OFFSETS="0 $((stride/2)) $((stride-1))"
4171         for offset in $OFFSETS; do
4172                 for i in $(seq 0 $((nstripe-1))); do
4173                         local GLOBALOFFSETS=""
4174                         # size in Bytes
4175                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4176                         local myfn=$DIR/d44a-$size
4177                         echo "--------writing $myfn at $size"
4178                         ll_sparseness_write $myfn $size ||
4179                                 error "ll_sparseness_write"
4180                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4181                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4182                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4183
4184                         for j in $(seq 0 $((nstripe-1))); do
4185                                 # size in Bytes
4186                                 size=$((((j + $nstripe )*$stride + $offset)))
4187                                 ll_sparseness_write $myfn $size ||
4188                                         error "ll_sparseness_write"
4189                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4190                         done
4191                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4192                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4193                         rm -f $myfn
4194                 done
4195         done
4196 }
4197 run_test 44a "test sparse pwrite ==============================="
4198
4199 dirty_osc_total() {
4200         tot=0
4201         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4202                 tot=$(($tot + $d))
4203         done
4204         echo $tot
4205 }
4206 do_dirty_record() {
4207         before=`dirty_osc_total`
4208         echo executing "\"$*\""
4209         eval $*
4210         after=`dirty_osc_total`
4211         echo before $before, after $after
4212 }
4213 test_45() {
4214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4215
4216         f="$DIR/f45"
4217         # Obtain grants from OST if it supports it
4218         echo blah > ${f}_grant
4219         stop_writeback
4220         sync
4221         do_dirty_record "echo blah > $f"
4222         [[ $before -eq $after ]] && error "write wasn't cached"
4223         do_dirty_record "> $f"
4224         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4225         do_dirty_record "echo blah > $f"
4226         [[ $before -eq $after ]] && error "write wasn't cached"
4227         do_dirty_record "sync"
4228         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4229         do_dirty_record "echo blah > $f"
4230         [[ $before -eq $after ]] && error "write wasn't cached"
4231         do_dirty_record "cancel_lru_locks osc"
4232         [[ $before -gt $after ]] ||
4233                 error "lock cancellation didn't lower dirty count"
4234         start_writeback
4235 }
4236 run_test 45 "osc io page accounting ============================"
4237
4238 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4239 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4240 # objects offset and an assert hit when an rpc was built with 1023's mapped
4241 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4242 test_46() {
4243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4244
4245         f="$DIR/f46"
4246         stop_writeback
4247         sync
4248         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4249         sync
4250         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4251         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4252         sync
4253         start_writeback
4254 }
4255 run_test 46 "dirtying a previously written page ================"
4256
4257 # test_47 is removed "Device nodes check" is moved to test_28
4258
4259 test_48a() { # bug 2399
4260         [ "$mds1_FSTYPE" = "zfs" ] &&
4261         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4262                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4263
4264         test_mkdir $DIR/$tdir
4265         cd $DIR/$tdir
4266         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4267         test_mkdir $DIR/$tdir
4268         touch foo || error "'touch foo' failed after recreating cwd"
4269         test_mkdir bar
4270         touch .foo || error "'touch .foo' failed after recreating cwd"
4271         test_mkdir .bar
4272         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4273         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4274         cd . || error "'cd .' failed after recreating cwd"
4275         mkdir . && error "'mkdir .' worked after recreating cwd"
4276         rmdir . && error "'rmdir .' worked after recreating cwd"
4277         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4278         cd .. || error "'cd ..' failed after recreating cwd"
4279 }
4280 run_test 48a "Access renamed working dir (should return errors)="
4281
4282 test_48b() { # bug 2399
4283         rm -rf $DIR/$tdir
4284         test_mkdir $DIR/$tdir
4285         cd $DIR/$tdir
4286         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4287         touch foo && error "'touch foo' worked after removing cwd"
4288         mkdir foo && error "'mkdir foo' worked after removing cwd"
4289         touch .foo && error "'touch .foo' worked after removing cwd"
4290         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4291         ls . > /dev/null && error "'ls .' worked after removing cwd"
4292         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4293         mkdir . && error "'mkdir .' worked after removing cwd"
4294         rmdir . && error "'rmdir .' worked after removing cwd"
4295         ln -s . foo && error "'ln -s .' worked after removing cwd"
4296         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4297 }
4298 run_test 48b "Access removed working dir (should return errors)="
4299
4300 test_48c() { # bug 2350
4301         #lctl set_param debug=-1
4302         #set -vx
4303         rm -rf $DIR/$tdir
4304         test_mkdir -p $DIR/$tdir/dir
4305         cd $DIR/$tdir/dir
4306         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4307         $TRACE touch foo && error "touch foo worked after removing cwd"
4308         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4309         touch .foo && error "touch .foo worked after removing cwd"
4310         mkdir .foo && error "mkdir .foo worked after removing cwd"
4311         $TRACE ls . && error "'ls .' worked after removing cwd"
4312         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4313         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4314         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4315         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4316         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4317 }
4318 run_test 48c "Access removed working subdir (should return errors)"
4319
4320 test_48d() { # bug 2350
4321         #lctl set_param debug=-1
4322         #set -vx
4323         rm -rf $DIR/$tdir
4324         test_mkdir -p $DIR/$tdir/dir
4325         cd $DIR/$tdir/dir
4326         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4327         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4328         $TRACE touch foo && error "'touch foo' worked after removing parent"
4329         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4330         touch .foo && error "'touch .foo' worked after removing parent"
4331         mkdir .foo && error "mkdir .foo worked after removing parent"
4332         $TRACE ls . && error "'ls .' worked after removing parent"
4333         $TRACE ls .. && error "'ls ..' worked after removing parent"
4334         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4335         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4336         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4337         true
4338 }
4339 run_test 48d "Access removed parent subdir (should return errors)"
4340
4341 test_48e() { # bug 4134
4342         #lctl set_param debug=-1
4343         #set -vx
4344         rm -rf $DIR/$tdir
4345         test_mkdir -p $DIR/$tdir/dir
4346         cd $DIR/$tdir/dir
4347         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4348         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4349         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4350         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4351         # On a buggy kernel addition of "touch foo" after cd .. will
4352         # produce kernel oops in lookup_hash_it
4353         touch ../foo && error "'cd ..' worked after recreate parent"
4354         cd $DIR
4355         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4356 }
4357 run_test 48e "Access to recreated parent subdir (should return errors)"
4358
4359 test_49() { # LU-1030
4360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4361         remote_ost_nodsh && skip "remote OST with nodsh"
4362
4363         # get ost1 size - lustre-OST0000
4364         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4365                 awk '{ print $4 }')
4366         # write 800M at maximum
4367         [[ $ost1_size -lt 2 ]] && ost1_size=2
4368         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4369
4370         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4371         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4372         local dd_pid=$!
4373
4374         # change max_pages_per_rpc while writing the file
4375         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4376         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4377         # loop until dd process exits
4378         while ps ax -opid | grep -wq $dd_pid; do
4379                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4380                 sleep $((RANDOM % 5 + 1))
4381         done
4382         # restore original max_pages_per_rpc
4383         $LCTL set_param $osc1_mppc=$orig_mppc
4384         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4385 }
4386 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4387
4388 test_50() {
4389         # bug 1485
4390         test_mkdir $DIR/$tdir
4391         cd $DIR/$tdir
4392         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4393 }
4394 run_test 50 "special situations: /proc symlinks  ==============="
4395
4396 test_51a() {    # was test_51
4397         # bug 1516 - create an empty entry right after ".." then split dir
4398         test_mkdir -c1 $DIR/$tdir
4399         touch $DIR/$tdir/foo
4400         $MCREATE $DIR/$tdir/bar
4401         rm $DIR/$tdir/foo
4402         createmany -m $DIR/$tdir/longfile 201
4403         FNUM=202
4404         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4405                 $MCREATE $DIR/$tdir/longfile$FNUM
4406                 FNUM=$(($FNUM + 1))
4407                 echo -n "+"
4408         done
4409         echo
4410         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4411 }
4412 run_test 51a "special situations: split htree with empty entry =="
4413
4414 cleanup_print_lfs_df () {
4415         trap 0
4416         $LFS df
4417         $LFS df -i
4418 }
4419
4420 test_51b() {
4421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4422
4423         local dir=$DIR/$tdir
4424         local nrdirs=$((65536 + 100))
4425
4426         # cleanup the directory
4427         rm -fr $dir
4428
4429         test_mkdir -c1 $dir
4430
4431         $LFS df
4432         $LFS df -i
4433         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4434         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4435         [[ $numfree -lt $nrdirs ]] &&
4436                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4437
4438         # need to check free space for the directories as well
4439         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4440         numfree=$(( blkfree / $(fs_inode_ksize) ))
4441         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4442
4443         trap cleanup_print_lfs_df EXIT
4444
4445         # create files
4446         createmany -d $dir/d $nrdirs || {
4447                 unlinkmany $dir/d $nrdirs
4448                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4449         }
4450
4451         # really created :
4452         nrdirs=$(ls -U $dir | wc -l)
4453
4454         # unlink all but 100 subdirectories, then check it still works
4455         local left=100
4456         local delete=$((nrdirs - left))
4457
4458         $LFS df
4459         $LFS df -i
4460
4461         # for ldiskfs the nlink count should be 1, but this is OSD specific
4462         # and so this is listed for informational purposes only
4463         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4464         unlinkmany -d $dir/d $delete ||
4465                 error "unlink of first $delete subdirs failed"
4466
4467         echo "nlink between: $(stat -c %h $dir)"
4468         local found=$(ls -U $dir | wc -l)
4469         [ $found -ne $left ] &&
4470                 error "can't find subdirs: found only $found, expected $left"
4471
4472         unlinkmany -d $dir/d $delete $left ||
4473                 error "unlink of second $left subdirs failed"
4474         # regardless of whether the backing filesystem tracks nlink accurately
4475         # or not, the nlink count shouldn't be more than "." and ".." here
4476         local after=$(stat -c %h $dir)
4477         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4478                 echo "nlink after: $after"
4479
4480         cleanup_print_lfs_df
4481 }
4482 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4483
4484 test_51d() {
4485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4486         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4487
4488         test_mkdir $DIR/$tdir
4489         createmany -o $DIR/$tdir/t- 1000
4490         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4491         for N in $(seq 0 $((OSTCOUNT - 1))); do
4492                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4493                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4494                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4495                         '($1 == '$N') { objs += 1 } \
4496                         END { printf("%0.0f", objs) }')
4497                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4498         done
4499         unlinkmany $DIR/$tdir/t- 1000
4500
4501         NLAST=0
4502         for N in $(seq 1 $((OSTCOUNT - 1))); do
4503                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4504                         error "OST $N has less objects vs OST $NLAST" \
4505                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4506                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4507                         error "OST $N has less objects vs OST $NLAST" \
4508                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4509
4510                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4511                         error "OST $N has less #0 objects vs OST $NLAST" \
4512                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4513                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4514                         error "OST $N has less #0 objects vs OST $NLAST" \
4515                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4516                 NLAST=$N
4517         done
4518         rm -f $TMP/$tfile
4519 }
4520 run_test 51d "check object distribution"
4521
4522 test_51e() {
4523         if [ "$mds1_FSTYPE" != ldiskfs ]; then
4524                 skip_env "ldiskfs only test"
4525         fi
4526
4527         test_mkdir -c1 $DIR/$tdir
4528         test_mkdir -c1 $DIR/$tdir/d0
4529
4530         touch $DIR/$tdir/d0/foo
4531         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
4532                 error "file exceed 65000 nlink limit!"
4533         unlinkmany $DIR/$tdir/d0/f- 65001
4534         return 0
4535 }
4536 run_test 51e "check file nlink limit"
4537
4538 test_51f() {
4539         test_mkdir $DIR/$tdir
4540
4541         local max=100000
4542         local ulimit_old=$(ulimit -n)
4543         local spare=20 # number of spare fd's for scripts/libraries, etc.
4544         local mdt=$($LFS getstripe -m $DIR/$tdir)
4545         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
4546
4547         echo "MDT$mdt numfree=$numfree, max=$max"
4548         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
4549         if [ $((numfree + spare)) -gt $ulimit_old ]; then
4550                 while ! ulimit -n $((numfree + spare)); do
4551                         numfree=$((numfree * 3 / 4))
4552                 done
4553                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
4554         else
4555                 echo "left ulimit at $ulimit_old"
4556         fi
4557
4558         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
4559                 unlinkmany $DIR/$tdir/f $numfree
4560                 error "create+open $numfree files in $DIR/$tdir failed"
4561         }
4562         ulimit -n $ulimit_old
4563
4564         # if createmany exits at 120s there will be fewer than $numfree files
4565         unlinkmany $DIR/$tdir/f $numfree || true
4566 }
4567 run_test 51f "check many open files limit"
4568
4569 test_52a() {
4570         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
4571         test_mkdir $DIR/$tdir
4572         touch $DIR/$tdir/foo
4573         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
4574         echo bar >> $DIR/$tdir/foo || error "append bar failed"
4575         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4576         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4577         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4578                                         error "link worked"
4579         echo foo >> $DIR/$tdir/foo || error "append foo failed"
4580         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4581         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
4582                                                      error "lsattr"
4583         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
4584         cp -r $DIR/$tdir $TMP/
4585         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
4586 }
4587 run_test 52a "append-only flag test (should return errors)"
4588
4589 test_52b() {
4590         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
4591         test_mkdir $DIR/$tdir
4592         touch $DIR/$tdir/foo
4593         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
4594         cat test > $DIR/$tdir/foo && error "cat test worked"
4595         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4596         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4597         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4598                                         error "link worked"
4599         echo foo >> $DIR/$tdir/foo && error "echo worked"
4600         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4601         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
4602         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
4603         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
4604                                                         error "lsattr"
4605         chattr -i $DIR/$tdir/foo || error "chattr failed"
4606
4607         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
4608 }
4609 run_test 52b "immutable flag test (should return errors) ======="
4610
4611 test_53() {
4612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4613         remote_mds_nodsh && skip "remote MDS with nodsh"
4614         remote_ost_nodsh && skip "remote OST with nodsh"
4615
4616         local param
4617         local param_seq
4618         local ostname
4619         local mds_last
4620         local mds_last_seq
4621         local ost_last
4622         local ost_last_seq
4623         local ost_last_id
4624         local ostnum
4625         local node
4626         local found=false
4627         local support_last_seq=true
4628
4629         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
4630                 support_last_seq=false
4631
4632         # only test MDT0000
4633         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
4634         local value
4635         for value in $(do_facet $SINGLEMDS \
4636                        $LCTL get_param osc.$mdtosc.prealloc_last_id) ; do
4637                 param=$(echo ${value[0]} | cut -d "=" -f1)
4638                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
4639
4640                 if $support_last_seq; then
4641                         param_seq=$(echo $param |
4642                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
4643                         mds_last_seq=$(do_facet $SINGLEMDS \
4644                                        $LCTL get_param -n $param_seq)
4645                 fi
4646                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
4647
4648                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
4649                 node=$(facet_active_host ost$((ostnum+1)))
4650                 param="obdfilter.$ostname.last_id"
4651                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
4652                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
4653                         ost_last_id=$ost_last
4654
4655                         if $support_last_seq; then
4656                                 ost_last_id=$(echo $ost_last |
4657                                               awk -F':' '{print $2}' |
4658                                               sed -e "s/^0x//g")
4659                                 ost_last_seq=$(echo $ost_last |
4660                                                awk -F':' '{print $1}')
4661                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
4662                         fi
4663
4664                         if [[ $ost_last_id != $mds_last ]]; then
4665                                 error "$ost_last_id != $mds_last"
4666                         else
4667                                 found=true
4668                                 break
4669                         fi
4670                 done
4671         done
4672         $found || error "can not match last_seq/last_id for $mdtosc"
4673         return 0
4674 }
4675 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
4676
4677 test_54a() {
4678         perl -MSocket -e ';' || skip "no Socket perl module installed"
4679
4680         $SOCKETSERVER $DIR/socket ||
4681                 error "$SOCKETSERVER $DIR/socket failed: $?"
4682         $SOCKETCLIENT $DIR/socket ||
4683                 error "$SOCKETCLIENT $DIR/socket failed: $?"
4684         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
4685 }
4686 run_test 54a "unix domain socket test =========================="
4687
4688 test_54b() {
4689         f="$DIR/f54b"
4690         mknod $f c 1 3
4691         chmod 0666 $f
4692         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
4693 }
4694 run_test 54b "char device works in lustre ======================"
4695
4696 find_loop_dev() {
4697         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
4698         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
4699         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
4700
4701         for i in $(seq 3 7); do
4702                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
4703                 LOOPDEV=$LOOPBASE$i
4704                 LOOPNUM=$i
4705                 break
4706         done
4707 }
4708
4709 cleanup_54c() {
4710         local rc=0
4711         loopdev="$DIR/loop54c"
4712
4713         trap 0
4714         $UMOUNT $DIR/$tdir || rc=$?
4715         losetup -d $loopdev || true
4716         losetup -d $LOOPDEV || true
4717         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
4718         return $rc
4719 }
4720
4721 test_54c() {
4722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4723
4724         loopdev="$DIR/loop54c"
4725
4726         find_loop_dev
4727         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
4728         trap cleanup_54c EXIT
4729         mknod $loopdev b 7 $LOOPNUM
4730         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
4731         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
4732         losetup $loopdev $DIR/$tfile ||
4733                 error "can't set up $loopdev for $DIR/$tfile"
4734         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
4735         test_mkdir $DIR/$tdir
4736         mount -t ext2 $loopdev $DIR/$tdir ||
4737                 error "error mounting $loopdev on $DIR/$tdir"
4738         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
4739                 error "dd write"
4740         df $DIR/$tdir
4741         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
4742                 error "dd read"
4743         cleanup_54c
4744 }
4745 run_test 54c "block device works in lustre ====================="
4746
4747 test_54d() {
4748         f="$DIR/f54d"
4749         string="aaaaaa"
4750         mknod $f p
4751         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
4752 }
4753 run_test 54d "fifo device works in lustre ======================"
4754
4755 test_54e() {
4756         f="$DIR/f54e"
4757         string="aaaaaa"
4758         cp -aL /dev/console $f
4759         echo $string > $f || error "echo $string to $f failed"
4760 }
4761 run_test 54e "console/tty device works in lustre ======================"
4762
4763 test_56a() {
4764         local numfiles=3
4765         local dir=$DIR/$tdir
4766
4767         rm -rf $dir
4768         test_mkdir -p $dir/dir
4769         for i in $(seq $numfiles); do
4770                 touch $dir/file$i
4771                 touch $dir/dir/file$i
4772         done
4773
4774         local numcomp=$($LFS getstripe --component-count $dir)
4775
4776         [[ $numcomp == 0 ]] && numcomp=1
4777
4778         # test lfs getstripe with --recursive
4779         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
4780
4781         [[ $filenum -eq $((numfiles * 2)) ]] ||
4782                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
4783         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
4784         [[ $filenum -eq $numfiles ]] ||
4785                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
4786         echo "$LFS getstripe showed obdidx or l_ost_idx"
4787
4788         # test lfs getstripe with file instead of dir
4789         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
4790         [[ $filenum -eq 1 ]] ||
4791                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
4792         echo "$LFS getstripe file1 passed"
4793
4794         #test lfs getstripe with --verbose
4795         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
4796         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4797                 error "$LFS getstripe --verbose $dir: "\
4798                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
4799         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
4800                 error "$LFS getstripe $dir: showed lmm_magic"
4801
4802         #test lfs getstripe with -v prints lmm_fid
4803         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
4804         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4805                 error "$LFS getstripe -v $dir: "\
4806                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
4807         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
4808                 error "$LFS getstripe $dir: showed lmm_fid by default"
4809         echo "$LFS getstripe --verbose passed"
4810
4811         #check for FID information
4812         local fid1=$($LFS getstripe --fid $dir/file1)
4813         local fid2=$($LFS getstripe --verbose $dir/file1 |
4814                      awk '/lmm_fid: / { print $2; exit; }')
4815         local fid3=$($LFS path2fid $dir/file1)
4816
4817         [ "$fid1" != "$fid2" ] &&
4818                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
4819         [ "$fid1" != "$fid3" ] &&
4820                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
4821         echo "$LFS getstripe --fid passed"
4822
4823         #test lfs getstripe with --obd
4824         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
4825                 error "$LFS getstripe --obd wrong_uuid: should return error"
4826
4827         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4828
4829         local ostidx=1
4830         local obduuid=$(ostuuid_from_index $ostidx)
4831         local found=$($LFS getstripe -r --obd $obduuid $dir |
4832                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
4833
4834         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
4835         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
4836                 ((filenum--))
4837         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
4838                 ((filenum--))
4839
4840         [[ $found -eq $filenum ]] ||
4841                 error "$LFS getstripe --obd: found $found expect $filenum"
4842         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
4843                 sed '/^[         ]*'${ostidx}'[  ]/d' |
4844                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
4845                 error "$LFS getstripe --obd: should not show file on other obd"
4846         echo "$LFS getstripe --obd passed"
4847 }
4848 run_test 56a "check $LFS getstripe"
4849
4850 test_56b() {
4851         local dir=$DIR/$tdir
4852         local numdirs=3
4853
4854         test_mkdir $dir
4855         for i in $(seq $numdirs); do
4856                 test_mkdir $dir/dir$i
4857         done
4858
4859         # test lfs getdirstripe default mode is non-recursion, which is
4860         # different from lfs getstripe
4861         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
4862
4863         [[ $dircnt -eq 1 ]] ||
4864                 error "$LFS getdirstripe: found $dircnt, not 1"
4865         dircnt=$($LFS getdirstripe --recursive $dir |
4866                 grep -c lmv_stripe_count)
4867         [[ $dircnt -eq $((numdirs + 1)) ]] ||
4868                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
4869 }
4870 run_test 56b "check $LFS getdirstripe"
4871
4872 test_56c() {
4873         remote_ost_nodsh && skip "remote OST with nodsh"
4874
4875         local ost_idx=0
4876         local ost_name=$(ostname_from_index $ost_idx)
4877         local old_status=$(ost_dev_status $ost_idx)
4878
4879         [[ -z "$old_status" ]] ||
4880                 skip_env "OST $ost_name is in $old_status status"
4881
4882         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
4883         sleep_maxage
4884
4885         local new_status=$(ost_dev_status $ost_idx)
4886
4887         [[ "$new_status" = "D" ]] ||
4888                 error "OST $ost_name is in status of '$new_status', not 'D'"
4889
4890         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
4891         sleep_maxage
4892
4893         new_status=$(ost_dev_status $ost_idx)
4894         [[ -z "$new_status" ]] ||
4895                 error "OST $ost_name is in status of '$new_status', not ''"
4896 }
4897 run_test 56c "check 'lfs df' showing device status"
4898
4899 NUMFILES=3
4900 NUMDIRS=3
4901 setup_56() {
4902         local local_tdir="$1"
4903         local local_numfiles="$2"
4904         local local_numdirs="$3"
4905         local dir_params="$4"
4906         local dir_stripe_params="$5"
4907
4908         if [ ! -d "$local_tdir" ] ; then
4909                 test_mkdir -p $dir_stripe_params $local_tdir
4910                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
4911                 for i in $(seq $local_numfiles) ; do
4912                         touch $local_tdir/file$i
4913                 done
4914                 for i in $(seq $local_numdirs) ; do
4915                         test_mkdir $dir_stripe_params $local_tdir/dir$i
4916                         for j in $(seq $local_numfiles) ; do
4917                                 touch $local_tdir/dir$i/file$j
4918                         done
4919                 done
4920         fi
4921 }
4922
4923 setup_56_special() {
4924         local local_tdir=$1
4925         local local_numfiles=$2
4926         local local_numdirs=$3
4927
4928         setup_56 $local_tdir $local_numfiles $local_numdirs
4929
4930         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
4931                 for i in $(seq $local_numfiles) ; do
4932                         mknod $local_tdir/loop${i}b b 7 $i
4933                         mknod $local_tdir/null${i}c c 1 3
4934                         ln -s $local_tdir/file1 $local_tdir/link${i}
4935                 done
4936                 for i in $(seq $local_numdirs) ; do
4937                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
4938                         mknod $local_tdir/dir$i/null${i}c c 1 3
4939                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
4940                 done
4941         fi
4942 }
4943
4944 test_56g() {
4945         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4946         local expected=$(($NUMDIRS + 2))
4947
4948         setup_56 $dir $NUMFILES $NUMDIRS
4949
4950         # test lfs find with -name
4951         for i in $(seq $NUMFILES) ; do
4952                 local nums=$($LFS find -name "*$i" $dir | wc -l)
4953
4954                 [ $nums -eq $expected ] ||
4955                         error "lfs find -name '*$i' $dir wrong: "\
4956                               "found $nums, expected $expected"
4957         done
4958 }
4959 run_test 56g "check lfs find -name"
4960
4961 test_56h() {
4962         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4963         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
4964
4965         setup_56 $dir $NUMFILES $NUMDIRS
4966
4967         # test lfs find with ! -name
4968         for i in $(seq $NUMFILES) ; do
4969                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
4970
4971                 [ $nums -eq $expected ] ||
4972                         error "lfs find ! -name '*$i' $dir wrong: "\
4973                               "found $nums, expected $expected"
4974         done
4975 }
4976 run_test 56h "check lfs find ! -name"
4977
4978 test_56i() {
4979         local dir=$DIR/$tdir
4980
4981         test_mkdir $dir
4982
4983         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
4984         local out=$($cmd)
4985
4986         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
4987 }
4988 run_test 56i "check 'lfs find -ost UUID' skips directories"
4989
4990 test_56j() {
4991         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4992
4993         setup_56_special $dir $NUMFILES $NUMDIRS
4994
4995         local expected=$((NUMDIRS + 1))
4996         local cmd="$LFS find -type d $dir"
4997         local nums=$($cmd | wc -l)
4998
4999         [ $nums -eq $expected ] ||
5000                 error "'$cmd' wrong: found $nums, expected $expected"
5001 }
5002 run_test 56j "check lfs find -type d"
5003
5004 test_56k() {
5005         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5006
5007         setup_56_special $dir $NUMFILES $NUMDIRS
5008
5009         local expected=$(((NUMDIRS + 1) * NUMFILES))
5010         local cmd="$LFS find -type f $dir"
5011         local nums=$($cmd | wc -l)
5012
5013         [ $nums -eq $expected ] ||
5014                 error "'$cmd' wrong: found $nums, expected $expected"
5015 }
5016 run_test 56k "check lfs find -type f"
5017
5018 test_56l() {
5019         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5020
5021         setup_56_special $dir $NUMFILES $NUMDIRS
5022
5023         local expected=$((NUMDIRS + NUMFILES))
5024         local cmd="$LFS find -type b $dir"
5025         local nums=$($cmd | wc -l)
5026
5027         [ $nums -eq $expected ] ||
5028                 error "'$cmd' wrong: found $nums, expected $expected"
5029 }
5030 run_test 56l "check lfs find -type b"
5031
5032 test_56m() {
5033         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5034
5035         setup_56_special $dir $NUMFILES $NUMDIRS
5036
5037         local expected=$((NUMDIRS + NUMFILES))
5038         local cmd="$LFS find -type c $dir"
5039         local nums=$($cmd | wc -l)
5040         [ $nums -eq $expected ] ||
5041                 error "'$cmd' wrong: found $nums, expected $expected"
5042 }
5043 run_test 56m "check lfs find -type c"
5044
5045 test_56n() {
5046         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5047         setup_56_special $dir $NUMFILES $NUMDIRS
5048
5049         local expected=$((NUMDIRS + NUMFILES))
5050         local cmd="$LFS find -type l $dir"
5051         local nums=$($cmd | wc -l)
5052
5053         [ $nums -eq $expected ] ||
5054                 error "'$cmd' wrong: found $nums, expected $expected"
5055 }
5056 run_test 56n "check lfs find -type l"
5057
5058 test_56o() {
5059         local dir=$DIR/$tdir
5060
5061         setup_56 $dir $NUMFILES $NUMDIRS
5062         utime $dir/file1 > /dev/null || error "utime (1)"
5063         utime $dir/file2 > /dev/null || error "utime (2)"
5064         utime $dir/dir1 > /dev/null || error "utime (3)"
5065         utime $dir/dir2 > /dev/null || error "utime (4)"
5066         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5067         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5068
5069         local expected=4
5070         local nums=$($LFS find -mtime +0 $dir | wc -l)
5071
5072         [ $nums -eq $expected ] ||
5073                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5074
5075         expected=12
5076         cmd="$LFS find -mtime 0 $dir"
5077         nums=$($cmd | wc -l)
5078         [ $nums -eq $expected ] ||
5079                 error "'$cmd' wrong: found $nums, expected $expected"
5080 }
5081 run_test 56o "check lfs find -mtime for old files"
5082
5083 test_56p() {
5084         [ $RUNAS_ID -eq $UID ] &&
5085                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5086
5087         local dir=$DIR/$tdir
5088
5089         setup_56 $dir $NUMFILES $NUMDIRS
5090         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5091
5092         local expected=$NUMFILES
5093         local cmd="$LFS find -uid $RUNAS_ID $dir"
5094         local nums=$($cmd | wc -l)
5095
5096         [ $nums -eq $expected ] ||
5097                 error "'$cmd' wrong: found $nums, expected $expected"
5098
5099         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5100         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5101         nums=$($cmd | wc -l)
5102         [ $nums -eq $expected ] ||
5103                 error "'$cmd' wrong: found $nums, expected $expected"
5104 }
5105 run_test 56p "check lfs find -uid and ! -uid"
5106
5107 test_56q() {
5108         [ $RUNAS_ID -eq $UID ] &&
5109                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5110
5111         local dir=$DIR/$tdir
5112
5113         setup_56 $dir $NUMFILES $NUMDIRS
5114         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5115
5116         local expected=$NUMFILES
5117         local cmd="$LFS find -gid $RUNAS_GID $dir"
5118         local nums=$($cmd | wc -l)
5119
5120         [ $nums -eq $expected ] ||
5121                 error "'$cmd' wrong: found $nums, expected $expected"
5122
5123         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5124         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5125         nums=$($cmd | wc -l)
5126         [ $nums -eq $expected ] ||
5127                 error "'$cmd' wrong: found $nums, expected $expected"
5128 }
5129 run_test 56q "check lfs find -gid and ! -gid"
5130
5131 test_56r() {
5132         local dir=$DIR/$tdir
5133
5134         setup_56 $dir $NUMFILES $NUMDIRS
5135
5136         local expected=12
5137         local cmd="$LFS find -size 0 -type f $dir"
5138         local nums=$($cmd | wc -l)
5139
5140         [ $nums -eq $expected ] ||
5141                 error "'$cmd' wrong: found $nums, expected $expected"
5142         expected=0
5143         cmd="$LFS find ! -size 0 -type f $dir"
5144         nums=$($cmd | wc -l)
5145         [ $nums -eq $expected ] ||
5146                 error "'$cmd' wrong: found $nums, expected $expected"
5147         echo "test" > $dir/$tfile
5148         echo "test2" > $dir/$tfile.2 && sync
5149         expected=1
5150         cmd="$LFS find -size 5 -type f $dir"
5151         nums=$($cmd | wc -l)
5152         [ $nums -eq $expected ] ||
5153                 error "'$cmd' wrong: found $nums, expected $expected"
5154         expected=1
5155         cmd="$LFS find -size +5 -type f $dir"
5156         nums=$($cmd | wc -l)
5157         [ $nums -eq $expected ] ||
5158                 error "'$cmd' wrong: found $nums, expected $expected"
5159         expected=2
5160         cmd="$LFS find -size +0 -type f $dir"
5161         nums=$($cmd | wc -l)
5162         [ $nums -eq $expected ] ||
5163                 error "'$cmd' wrong: found $nums, expected $expected"
5164         expected=2
5165         cmd="$LFS find ! -size -5 -type f $dir"
5166         nums=$($cmd | wc -l)
5167         [ $nums -eq $expected ] ||
5168                 error "'$cmd' wrong: found $nums, expected $expected"
5169         expected=12
5170         cmd="$LFS find -size -5 -type f $dir"
5171         nums=$($cmd | wc -l)
5172         [ $nums -eq $expected ] ||
5173                 error "'$cmd' wrong: found $nums, expected $expected"
5174 }
5175 run_test 56r "check lfs find -size works"
5176
5177 test_56s() { # LU-611 #LU-9369
5178         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5179
5180         local dir=$DIR/$tdir
5181         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5182
5183         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5184         for i in $(seq $NUMDIRS); do
5185                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5186         done
5187
5188         local expected=$NUMDIRS
5189         local cmd="$LFS find -c $OSTCOUNT $dir"
5190         local nums=$($cmd | wc -l)
5191
5192         [ $nums -eq $expected ] || {
5193                 $LFS getstripe -R $dir
5194                 error "'$cmd' wrong: found $nums, expected $expected"
5195         }
5196
5197         expected=$((NUMDIRS + onestripe))
5198         cmd="$LFS find -stripe-count +0 -type f $dir"
5199         nums=$($cmd | wc -l)
5200         [ $nums -eq $expected ] || {
5201                 $LFS getstripe -R $dir
5202                 error "'$cmd' wrong: found $nums, expected $expected"
5203         }
5204
5205         expected=$onestripe
5206         cmd="$LFS find -stripe-count 1 -type f $dir"
5207         nums=$($cmd | wc -l)
5208         [ $nums -eq $expected ] || {
5209                 $LFS getstripe -R $dir
5210                 error "'$cmd' wrong: found $nums, expected $expected"
5211         }
5212
5213         cmd="$LFS find -stripe-count -2 -type f $dir"
5214         nums=$($cmd | wc -l)
5215         [ $nums -eq $expected ] || {
5216                 $LFS getstripe -R $dir
5217                 error "'$cmd' wrong: found $nums, expected $expected"
5218         }
5219
5220         expected=0
5221         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5222         nums=$($cmd | wc -l)
5223         [ $nums -eq $expected ] || {
5224                 $LFS getstripe -R $dir
5225                 error "'$cmd' wrong: found $nums, expected $expected"
5226         }
5227 }
5228 run_test 56s "check lfs find -stripe-count works"
5229
5230 test_56t() { # LU-611 #LU-9369
5231         local dir=$DIR/$tdir
5232
5233         setup_56 $dir 0 $NUMDIRS
5234         for i in $(seq $NUMDIRS); do
5235                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5236         done
5237
5238         local expected=$NUMDIRS
5239         local cmd="$LFS find -S 8M $dir"
5240         local nums=$($cmd | wc -l)
5241
5242         [ $nums -eq $expected ] || {
5243                 $LFS getstripe -R $dir
5244                 error "'$cmd' wrong: found $nums, expected $expected"
5245         }
5246         rm -rf $dir
5247
5248         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5249
5250         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5251
5252         expected=$(((NUMDIRS + 1) * NUMFILES))
5253         cmd="$LFS find -stripe-size 512k -type f $dir"
5254         nums=$($cmd | wc -l)
5255         [ $nums -eq $expected ] ||
5256                 error "'$cmd' wrong: found $nums, expected $expected"
5257
5258         cmd="$LFS find -stripe-size +320k -type f $dir"
5259         nums=$($cmd | wc -l)
5260         [ $nums -eq $expected ] ||
5261                 error "'$cmd' wrong: found $nums, expected $expected"
5262
5263         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5264         cmd="$LFS find -stripe-size +200k -type f $dir"
5265         nums=$($cmd | wc -l)
5266         [ $nums -eq $expected ] ||
5267                 error "'$cmd' wrong: found $nums, expected $expected"
5268
5269         cmd="$LFS find -stripe-size -640k -type f $dir"
5270         nums=$($cmd | wc -l)
5271         [ $nums -eq $expected ] ||
5272                 error "'$cmd' wrong: found $nums, expected $expected"
5273
5274         expected=4
5275         cmd="$LFS find -stripe-size 256k -type f $dir"
5276         nums=$($cmd | wc -l)
5277         [ $nums -eq $expected ] ||
5278                 error "'$cmd' wrong: found $nums, expected $expected"
5279
5280         cmd="$LFS find -stripe-size -320k -type f $dir"
5281         nums=$($cmd | wc -l)
5282         [ $nums -eq $expected ] ||
5283                 error "'$cmd' wrong: found $nums, expected $expected"
5284
5285         expected=0
5286         cmd="$LFS find -stripe-size 1024k -type f $dir"
5287         nums=$($cmd | wc -l)
5288         [ $nums -eq $expected ] ||
5289                 error "'$cmd' wrong: found $nums, expected $expected"
5290 }
5291 run_test 56t "check lfs find -stripe-size works"
5292
5293 test_56u() { # LU-611
5294         local dir=$DIR/$tdir
5295
5296         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5297
5298         if [[ $OSTCOUNT -gt 1 ]]; then
5299                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5300                 onestripe=4
5301         else
5302                 onestripe=0
5303         fi
5304
5305         local expected=$(((NUMDIRS + 1) * NUMFILES))
5306         local cmd="$LFS find -stripe-index 0 -type f $dir"
5307         local nums=$($cmd | wc -l)
5308
5309         [ $nums -eq $expected ] ||
5310                 error "'$cmd' wrong: found $nums, expected $expected"
5311
5312         expected=$onestripe
5313         cmd="$LFS find -stripe-index 1 -type f $dir"
5314         nums=$($cmd | wc -l)
5315         [ $nums -eq $expected ] ||
5316                 error "'$cmd' wrong: found $nums, expected $expected"
5317
5318         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5319         nums=$($cmd | wc -l)
5320         [ $nums -eq $expected ] ||
5321                 error "'$cmd' wrong: found $nums, expected $expected"
5322
5323         expected=0
5324         # This should produce an error and not return any files
5325         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5326         nums=$($cmd 2>/dev/null | wc -l)
5327         [ $nums -eq $expected ] ||
5328                 error "'$cmd' wrong: found $nums, expected $expected"
5329
5330         if [[ $OSTCOUNT -gt 1 ]]; then
5331                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5332                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5333                 nums=$($cmd | wc -l)
5334                 [ $nums -eq $expected ] ||
5335                         error "'$cmd' wrong: found $nums, expected $expected"
5336         fi
5337 }
5338 run_test 56u "check lfs find -stripe-index works"
5339
5340 test_56v() {
5341         local mdt_idx=0
5342         local dir=$DIR/$tdir
5343
5344         setup_56 $dir $NUMFILES $NUMDIRS
5345
5346         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5347         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5348
5349         for file in $($LFS find -m $UUID $dir); do
5350                 file_midx=$($LFS getstripe -m $file)
5351                 [ $file_midx -eq $mdt_idx ] ||
5352                         error "lfs find -m $UUID != getstripe -m $file_midx"
5353         done
5354 }
5355 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5356
5357 test_56w() {
5358         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5360
5361         local dir=$DIR/$tdir
5362
5363         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5364
5365         local stripe_size=$($LFS getstripe -S -d $dir) ||
5366                 error "$LFS getstripe -S -d $dir failed"
5367         stripe_size=${stripe_size%% *}
5368
5369         local file_size=$((stripe_size * OSTCOUNT))
5370         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5371         local required_space=$((file_num * file_size))
5372         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5373                            head -n1)
5374         [[ $free_space -le $((required_space / 1024)) ]] &&
5375                 skip_env "need $required_space, have $free_space kbytes"
5376
5377         local dd_bs=65536
5378         local dd_count=$((file_size / dd_bs))
5379
5380         # write data into the files
5381         local i
5382         local j
5383         local file
5384
5385         for i in $(seq $NUMFILES); do
5386                 file=$dir/file$i
5387                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5388                         error "write data into $file failed"
5389         done
5390         for i in $(seq $NUMDIRS); do
5391                 for j in $(seq $NUMFILES); do
5392                         file=$dir/dir$i/file$j
5393                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5394                                 error "write data into $file failed"
5395                 done
5396         done
5397
5398         # $LFS_MIGRATE will fail if hard link migration is unsupported
5399         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5400                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5401                         error "creating links to $dir/dir1/file1 failed"
5402         fi
5403
5404         local expected=-1
5405
5406         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5407
5408         # lfs_migrate file
5409         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5410
5411         echo "$cmd"
5412         eval $cmd || error "$cmd failed"
5413
5414         check_stripe_count $dir/file1 $expected
5415
5416         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5417         then
5418                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5419                 # OST 1 if it is on OST 0. This file is small enough to
5420                 # be on only one stripe.
5421                 file=$dir/migr_1_ost
5422                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5423                         error "write data into $file failed"
5424                 local obdidx=$($LFS getstripe -i $file)
5425                 local oldmd5=$(md5sum $file)
5426                 local newobdidx=0
5427
5428                 [[ $obdidx -eq 0 ]] && newobdidx=1
5429                 cmd="$LFS migrate -i $newobdidx $file"
5430                 echo $cmd
5431                 eval $cmd || error "$cmd failed"
5432
5433                 local realobdix=$($LFS getstripe -i $file)
5434                 local newmd5=$(md5sum $file)
5435
5436                 [[ $newobdidx -ne $realobdix ]] &&
5437                         error "new OST is different (was=$obdidx, "\
5438                               "wanted=$newobdidx, got=$realobdix)"
5439                 [[ "$oldmd5" != "$newmd5" ]] &&
5440                         error "md5sum differ: $oldmd5, $newmd5"
5441         fi
5442
5443         # lfs_migrate dir
5444         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5445         echo "$cmd"
5446         eval $cmd || error "$cmd failed"
5447
5448         for j in $(seq $NUMFILES); do
5449                 check_stripe_count $dir/dir1/file$j $expected
5450         done
5451
5452         # lfs_migrate works with lfs find
5453         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5454              $LFS_MIGRATE -y -c $expected"
5455         echo "$cmd"
5456         eval $cmd || error "$cmd failed"
5457
5458         for i in $(seq 2 $NUMFILES); do
5459                 check_stripe_count $dir/file$i $expected
5460         done
5461         for i in $(seq 2 $NUMDIRS); do
5462                 for j in $(seq $NUMFILES); do
5463                 check_stripe_count $dir/dir$i/file$j $expected
5464                 done
5465         done
5466 }
5467 run_test 56w "check lfs_migrate -c stripe_count works"
5468
5469 test_56wb() {
5470         local file1=$DIR/$tdir/file1
5471         local create_pool=false
5472         local initial_pool=$($LFS getstripe -p $DIR)
5473         local pool_list=()
5474         local pool=""
5475
5476         echo -n "Creating test dir..."
5477         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5478         echo "done."
5479
5480         echo -n "Creating test file..."
5481         touch $file1 || error "cannot create file"
5482         echo "done."
5483
5484         echo -n "Detecting existing pools..."
5485         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
5486
5487         if [ ${#pool_list[@]} -gt 0 ]; then
5488                 echo "${pool_list[@]}"
5489                 for thispool in "${pool_list[@]}"; do
5490                         if [[ -z "$initial_pool" ||
5491                               "$initial_pool" != "$thispool" ]]; then
5492                                 pool="$thispool"
5493                                 echo "Using existing pool '$pool'"
5494                                 break
5495                         fi
5496                 done
5497         else
5498                 echo "none detected."
5499         fi
5500         if [ -z "$pool" ]; then
5501                 pool=${POOL:-testpool}
5502                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
5503                 echo -n "Creating pool '$pool'..."
5504                 create_pool=true
5505                 pool_add $pool &> /dev/null ||
5506                         error "pool_add failed"
5507                 echo "done."
5508
5509                 echo -n "Adding target to pool..."
5510                 pool_add_targets $pool 0 0 1 &> /dev/null ||
5511                         error "pool_add_targets failed"
5512                 echo "done."
5513         fi
5514
5515         echo -n "Setting pool using -p option..."
5516         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
5517                 error "migrate failed rc = $?"
5518         echo "done."
5519
5520         echo -n "Verifying test file is in pool after migrating..."
5521         [ "$($LFS getstripe -p $file1)" = $pool ] ||
5522                 error "file was not migrated to pool $pool"
5523         echo "done."
5524
5525         echo -n "Removing test file from pool '$pool'..."
5526         $LFS migrate $file1 &> /dev/null ||
5527                 error "cannot remove from pool"
5528         [ "$($LFS getstripe -p $file1)" ] &&
5529                 error "pool still set"
5530         echo "done."
5531
5532         echo -n "Setting pool using --pool option..."
5533         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
5534                 error "migrate failed rc = $?"
5535         echo "done."
5536
5537         # Clean up
5538         rm -f $file1
5539         if $create_pool; then
5540                 destroy_test_pools 2> /dev/null ||
5541                         error "destroy test pools failed"
5542         fi
5543 }
5544 run_test 56wb "check lfs_migrate pool support"
5545
5546 test_56wc() {
5547         local file1="$DIR/$tdir/file1"
5548
5549         echo -n "Creating test dir..."
5550         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5551         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
5552         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5553                 error "cannot set stripe"
5554         echo "done"
5555
5556         echo -n "Setting initial stripe for test file..."
5557         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
5558                 error "cannot set stripe"
5559         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5560                 error "stripe size not set"
5561         echo "done."
5562
5563         # File currently set to -S 512K -c 1
5564
5565         # Ensure -c and -S options are rejected when -R is set
5566         echo -n "Verifying incompatible options are detected..."
5567         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
5568                 error "incompatible -c and -R options not detected"
5569         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
5570                 error "incompatible -S and -R options not detected"
5571         echo "done."
5572
5573         # Ensure unrecognized options are passed through to 'lfs migrate'
5574         echo -n "Verifying -S option is passed through to lfs migrate..."
5575         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
5576                 error "migration failed"
5577         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
5578                 error "file was not restriped"
5579         echo "done."
5580
5581         # File currently set to -S 1M -c 1
5582
5583         # Ensure long options are supported
5584         echo -n "Verifying long options supported..."
5585         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
5586                 error "long option without argument not supported"
5587         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
5588                 error "long option with argument not supported"
5589         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5590                 error "file not restriped with --stripe-size option"
5591         echo "done."
5592
5593         # File currently set to -S 512K -c 1
5594
5595         if [ "$OSTCOUNT" -gt 1 ]; then
5596                 echo -n "Verifying explicit stripe count can be set..."
5597                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
5598                         error "migrate failed"
5599                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
5600                         error "file not restriped to explicit count"
5601                 echo "done."
5602         fi
5603
5604         # File currently set to -S 512K -c 1 or -S 512K -c 2
5605
5606         # Ensure parent striping is used if -R is set, and no stripe
5607         # count or size is specified
5608         echo -n "Setting stripe for parent directory..."
5609         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5610                 error "cannot set stripe"
5611         echo "done."
5612
5613         echo -n "Verifying restripe option uses parent stripe settings..."
5614         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
5615                 error "migrate failed"
5616         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
5617                 error "file not restriped to parent settings"
5618         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
5619                 error "file not restriped to parent settings"
5620         echo "done."
5621
5622         # File currently set to -S 1M -c 1
5623
5624         # Ensure striping is preserved if -R is not set, and no stripe
5625         # count or size is specified
5626         echo -n "Verifying striping size preserved when not specified..."
5627         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
5628         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
5629                 error "cannot set stripe on parent directory"
5630         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5631                 error "migrate failed"
5632         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
5633                 error "file was restriped"
5634         echo "done."
5635
5636         # Ensure file name properly detected when final option has no argument
5637         echo -n "Verifying file name properly detected..."
5638         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5639                 error "file name interpreted as option argument"
5640         echo "done."
5641
5642         # Clean up
5643         rm -f "$file1"
5644 }
5645 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
5646
5647 test_56wd() {
5648         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5649
5650         local file1=$DIR/$tdir/file1
5651
5652         echo -n "Creating test dir..."
5653         test_mkdir $DIR/$tdir || error "cannot create dir"
5654         echo "done."
5655
5656         echo -n "Creating test file..."
5657         touch $file1
5658         echo "done."
5659
5660         # Ensure 'lfs migrate' will fail by using a non-existent option,
5661         # and make sure rsync is not called to recover
5662         echo -n "Make sure --no-rsync option works..."
5663         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
5664                 grep -q 'refusing to fall back to rsync' ||
5665                 error "rsync was called with --no-rsync set"
5666         echo "done."
5667
5668         # Ensure rsync is called without trying 'lfs migrate' first
5669         echo -n "Make sure --rsync option works..."
5670         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
5671                 grep -q 'falling back to rsync' &&
5672                 error "lfs migrate was called with --rsync set"
5673         echo "done."
5674
5675         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
5676         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
5677                 grep -q 'at the same time' ||
5678                 error "--rsync and --no-rsync accepted concurrently"
5679         echo "done."
5680
5681         # Clean up
5682         rm -f $file1
5683 }
5684 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
5685
5686 test_56x() {
5687         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5688         check_swap_layouts_support
5689
5690         local dir=$DIR/$tdir
5691         local ref1=/etc/passwd
5692         local file1=$dir/file1
5693
5694         test_mkdir $dir || error "creating dir $dir"
5695         $LFS setstripe -c 2 $file1
5696         cp $ref1 $file1
5697         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
5698         stripe=$($LFS getstripe -c $file1)
5699         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5700         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5701
5702         # clean up
5703         rm -f $file1
5704 }
5705 run_test 56x "lfs migration support"
5706
5707 test_56xa() {
5708         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5709         check_swap_layouts_support
5710
5711         local dir=$DIR/$tdir/$testnum
5712
5713         test_mkdir -p $dir
5714
5715         local ref1=/etc/passwd
5716         local file1=$dir/file1
5717
5718         $LFS setstripe -c 2 $file1
5719         cp $ref1 $file1
5720         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
5721
5722         local stripe=$($LFS getstripe -c $file1)
5723
5724         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5725         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5726
5727         # clean up
5728         rm -f $file1
5729 }
5730 run_test 56xa "lfs migration --block support"
5731
5732 check_migrate_links() {
5733         local dir="$1"
5734         local file1="$dir/file1"
5735         local begin="$2"
5736         local count="$3"
5737         local total_count=$(($begin + $count - 1))
5738         local symlink_count=10
5739         local uniq_count=10
5740
5741         if [ ! -f "$file1" ]; then
5742                 echo -n "creating initial file..."
5743                 $LFS setstripe -c 1 -S "512k" "$file1" ||
5744                         error "cannot setstripe initial file"
5745                 echo "done"
5746
5747                 echo -n "creating symlinks..."
5748                 for s in $(seq 1 $symlink_count); do
5749                         ln -s "$file1" "$dir/slink$s" ||
5750                                 error "cannot create symlinks"
5751                 done
5752                 echo "done"
5753
5754                 echo -n "creating nonlinked files..."
5755                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
5756                         error "cannot create nonlinked files"
5757                 echo "done"
5758         fi
5759
5760         # create hard links
5761         if [ ! -f "$dir/file$total_count" ]; then
5762                 echo -n "creating hard links $begin:$total_count..."
5763                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
5764                         /dev/null || error "cannot create hard links"
5765                 echo "done"
5766         fi
5767
5768         echo -n "checking number of hard links listed in xattrs..."
5769         local fid=$($LFS getstripe -F "$file1")
5770         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
5771
5772         echo "${#paths[*]}"
5773         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
5774                         skip "hard link list has unexpected size, skipping test"
5775         fi
5776         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
5777                         error "link names should exceed xattrs size"
5778         fi
5779
5780         echo -n "migrating files..."
5781         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
5782         local rc=$?
5783         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
5784         echo "done"
5785
5786         # make sure all links have been properly migrated
5787         echo -n "verifying files..."
5788         fid=$($LFS getstripe -F "$file1") ||
5789                 error "cannot get fid for file $file1"
5790         for i in $(seq 2 $total_count); do
5791                 local fid2=$($LFS getstripe -F $dir/file$i)
5792
5793                 [ "$fid2" == "$fid" ] ||
5794                         error "migrated hard link has mismatched FID"
5795         done
5796
5797         # make sure hard links were properly detected, and migration was
5798         # performed only once for the entire link set; nonlinked files should
5799         # also be migrated
5800         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
5801         local expected=$(($uniq_count + 1))
5802
5803         [ "$actual" -eq  "$expected" ] ||
5804                 error "hard links individually migrated ($actual != $expected)"
5805
5806         # make sure the correct number of hard links are present
5807         local hardlinks=$(stat -c '%h' "$file1")
5808
5809         [ $hardlinks -eq $total_count ] ||
5810                 error "num hard links $hardlinks != $total_count"
5811         echo "done"
5812
5813         return 0
5814 }
5815
5816 test_56xb() {
5817         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
5818                 skip "Need MDS version at least 2.10.55"
5819
5820         local dir="$DIR/$tdir"
5821
5822         test_mkdir "$dir" || error "cannot create dir $dir"
5823
5824         echo "testing lfs migrate mode when all links fit within xattrs"
5825         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
5826
5827         echo "testing rsync mode when all links fit within xattrs"
5828         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
5829
5830         echo "testing lfs migrate mode when all links do not fit within xattrs"
5831         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
5832
5833         echo "testing rsync mode when all links do not fit within xattrs"
5834         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
5835
5836
5837         # clean up
5838         rm -rf $dir
5839 }
5840 run_test 56xb "lfs migration hard link support"
5841
5842 test_56xc() {
5843         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5844
5845         local dir="$DIR/$tdir"
5846
5847         test_mkdir "$dir" || error "cannot create dir $dir"
5848
5849         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
5850         echo -n "Setting initial stripe for 20MB test file..."
5851         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
5852         echo "done"
5853         echo -n "Sizing 20MB test file..."
5854         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
5855         echo "done"
5856         echo -n "Verifying small file autostripe count is 1..."
5857         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
5858                 error "cannot migrate 20MB file"
5859         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
5860                 error "cannot get stripe for $dir/20mb"
5861         [ $stripe_count -eq 1 ] ||
5862                 error "unexpected stripe count $stripe_count for 20MB file"
5863         rm -f "$dir/20mb"
5864         echo "done"
5865
5866         # Test 2: File is small enough to fit within the available space on
5867         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
5868         # have at least an additional 1KB for each desired stripe for test 3
5869         echo -n "Setting stripe for 1GB test file..."
5870         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
5871         echo "done"
5872         echo -n "Sizing 1GB test file..."
5873         # File size is 1GB + 3KB
5874         truncate "$dir/1gb" 1073744896 &> /dev/null ||
5875                 error "cannot create 1GB test file"
5876         echo "done"
5877         echo -n "Migrating 1GB file..."
5878         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
5879                 error "cannot migrate file"
5880         echo "done"
5881         echo -n "Verifying autostripe count is sqrt(n) + 1..."
5882         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
5883                 error "cannot get stripe for $dir/1gb"
5884         [ $stripe_count -eq 2 ] ||
5885                 error "unexpected stripe count $stripe_count (expected 2)"
5886         echo "done"
5887
5888         # Test 3: File is too large to fit within the available space on
5889         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
5890         if [ $OSTCOUNT -ge 3 ]; then
5891                 # The required available space is calculated as
5892                 # file size (1GB + 3KB) / OST count (3).
5893                 local kb_per_ost=349526
5894
5895                 echo -n "Migrating 1GB file..."
5896                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
5897                         /dev/null || error "cannot migrate file"
5898                 echo "done"
5899
5900                 stripe_count=$($LFS getstripe -c "$dir/1gb")
5901                 echo -n "Verifying autostripe count with limited space..."
5902                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
5903                         error "unexpected stripe count $stripe_count (wanted 3)"
5904                 echo "done"
5905         fi
5906
5907         # clean up
5908         rm -rf $dir
5909 }
5910 run_test 56xc "lfs migration autostripe"
5911
5912 test_56y() {
5913         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
5914                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
5915
5916         local res=""
5917         local dir=$DIR/$tdir
5918         local f1=$dir/file1
5919         local f2=$dir/file2
5920
5921         test_mkdir -p $dir || error "creating dir $dir"
5922         touch $f1 || error "creating std file $f1"
5923         $MULTIOP $f2 H2c || error "creating released file $f2"
5924
5925         # a directory can be raid0, so ask only for files
5926         res=$($LFS find $dir -L raid0 -type f | wc -l)
5927         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
5928
5929         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
5930         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
5931
5932         # only files can be released, so no need to force file search
5933         res=$($LFS find $dir -L released)
5934         [[ $res == $f2 ]] || error "search released: found $res != $f2"
5935
5936         res=$($LFS find $dir -type f \! -L released)
5937         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
5938 }
5939 run_test 56y "lfs find -L raid0|released"
5940
5941 test_56z() { # LU-4824
5942         # This checks to make sure 'lfs find' continues after errors
5943         # There are two classes of errors that should be caught:
5944         # - If multiple paths are provided, all should be searched even if one
5945         #   errors out
5946         # - If errors are encountered during the search, it should not terminate
5947         #   early
5948         local dir=$DIR/$tdir
5949         local i
5950
5951         test_mkdir $dir
5952         for i in d{0..9}; do
5953                 test_mkdir $dir/$i
5954         done
5955         touch $dir/d{0..9}/$tfile
5956         $LFS find $DIR/non_existent_dir $dir &&
5957                 error "$LFS find did not return an error"
5958         # Make a directory unsearchable. This should NOT be the last entry in
5959         # directory order.  Arbitrarily pick the 6th entry
5960         chmod 700 $($LFS find $dir -type d | sed '6!d')
5961
5962         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
5963
5964         # The user should be able to see 10 directories and 9 files
5965         [ $count == 19 ] || error "$LFS find did not continue after error"
5966 }
5967 run_test 56z "lfs find should continue after an error"
5968
5969 test_56aa() { # LU-5937
5970         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
5971
5972         local dir=$DIR/$tdir
5973
5974         mkdir $dir
5975         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
5976
5977         createmany -o $dir/striped_dir/${tfile}- 1024
5978         local dirs=$($LFS find --size +8k $dir/)
5979
5980         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
5981 }
5982 run_test 56aa "lfs find --size under striped dir"
5983
5984 test_56ab() { # LU-10705
5985         test_mkdir $DIR/$tdir
5986         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
5987         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
5988         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
5989         # Flush writes to ensure valid blocks.  Need to be more thorough for
5990         # ZFS, since blocks are not allocated/returned to client immediately.
5991         sync_all_data
5992         wait_zfs_commit ost1 2
5993         cancel_lru_locks osc
5994         ls -ls $DIR/$tdir
5995
5996         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
5997
5998         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
5999
6000         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6001         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6002
6003         rm -f $DIR/$tdir/$tfile.[123]
6004 }
6005 run_test 56ab "lfs find --blocks"
6006
6007 test_56ba() {
6008         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6009                 skip "Need MDS version at least 2.10.50"
6010
6011         # Create composite files with one component
6012         local dir=$DIR/$tdir
6013
6014         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6015         # Create composite files with three components
6016         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6017         # Create non-composite files
6018         createmany -o $dir/${tfile}- 10
6019
6020         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6021
6022         [[ $nfiles == 10 ]] ||
6023                 error "lfs find -E 1M found $nfiles != 10 files"
6024
6025         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6026         [[ $nfiles == 25 ]] ||
6027                 error "lfs find ! -E 1M found $nfiles != 25 files"
6028
6029         # All files have a component that starts at 0
6030         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6031         [[ $nfiles == 35 ]] ||
6032                 error "lfs find --component-start 0 - $nfiles != 35 files"
6033
6034         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6035         [[ $nfiles == 15 ]] ||
6036                 error "lfs find --component-start 2M - $nfiles != 15 files"
6037
6038         # All files created here have a componenet that does not starts at 2M
6039         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6040         [[ $nfiles == 35 ]] ||
6041                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6042
6043         # Find files with a specified number of components
6044         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6045         [[ $nfiles == 15 ]] ||
6046                 error "lfs find --component-count 3 - $nfiles != 15 files"
6047
6048         # Remember non-composite files have a component count of zero
6049         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6050         [[ $nfiles == 10 ]] ||
6051                 error "lfs find --component-count 0 - $nfiles != 10 files"
6052
6053         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6054         [[ $nfiles == 20 ]] ||
6055                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6056
6057         # All files have a flag called "init"
6058         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6059         [[ $nfiles == 35 ]] ||
6060                 error "lfs find --component-flags init - $nfiles != 35 files"
6061
6062         # Multi-component files will have a component not initialized
6063         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6064         [[ $nfiles == 15 ]] ||
6065                 error "lfs find !--component-flags init - $nfiles != 15 files"
6066
6067         rm -rf $dir
6068
6069 }
6070 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6071
6072 test_56ca() {
6073         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6074                 skip "Need MDS version at least 2.10.57"
6075
6076         local td=$DIR/$tdir
6077         local tf=$td/$tfile
6078         local dir
6079         local nfiles
6080         local cmd
6081         local i
6082         local j
6083
6084         # create mirrored directories and mirrored files
6085         mkdir $td || error "mkdir $td failed"
6086         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6087         createmany -o $tf- 10 || error "create $tf- failed"
6088
6089         for i in $(seq 2); do
6090                 dir=$td/dir$i
6091                 mkdir $dir || error "mkdir $dir failed"
6092                 $LFS mirror create -N$((3 + i)) $dir ||
6093                         error "create mirrored dir $dir failed"
6094                 createmany -o $dir/$tfile- 10 ||
6095                         error "create $dir/$tfile- failed"
6096         done
6097
6098         # change the states of some mirrored files
6099         echo foo > $tf-6
6100         for i in $(seq 2); do
6101                 dir=$td/dir$i
6102                 for j in $(seq 4 9); do
6103                         echo foo > $dir/$tfile-$j
6104                 done
6105         done
6106
6107         # find mirrored files with specific mirror count
6108         cmd="$LFS find --mirror-count 3 --type f $td"
6109         nfiles=$($cmd | wc -l)
6110         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6111
6112         cmd="$LFS find ! --mirror-count 3 --type f $td"
6113         nfiles=$($cmd | wc -l)
6114         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6115
6116         cmd="$LFS find --mirror-count +2 --type f $td"
6117         nfiles=$($cmd | wc -l)
6118         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6119
6120         cmd="$LFS find --mirror-count -6 --type f $td"
6121         nfiles=$($cmd | wc -l)
6122         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6123
6124         # find mirrored files with specific file state
6125         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6126         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6127
6128         cmd="$LFS find --mirror-state=ro --type f $td"
6129         nfiles=$($cmd | wc -l)
6130         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6131
6132         cmd="$LFS find ! --mirror-state=ro --type f $td"
6133         nfiles=$($cmd | wc -l)
6134         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6135
6136         cmd="$LFS find --mirror-state=wp --type f $td"
6137         nfiles=$($cmd | wc -l)
6138         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6139
6140         cmd="$LFS find ! --mirror-state=sp --type f $td"
6141         nfiles=$($cmd | wc -l)
6142         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6143 }
6144 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6145
6146 test_57a() {
6147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6148         # note test will not do anything if MDS is not local
6149         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6150                 skip_env "ldiskfs only test"
6151         fi
6152         remote_mds_nodsh && skip "remote MDS with nodsh"
6153
6154         local MNTDEV="osd*.*MDT*.mntdev"
6155         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6156         [ -z "$DEV" ] && error "can't access $MNTDEV"
6157         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6158                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6159                         error "can't access $DEV"
6160                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6161                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6162                 rm $TMP/t57a.dump
6163         done
6164 }
6165 run_test 57a "verify MDS filesystem created with large inodes =="
6166
6167 test_57b() {
6168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6169         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6170                 skip_env "ldiskfs only test"
6171         fi
6172         remote_mds_nodsh && skip "remote MDS with nodsh"
6173
6174         local dir=$DIR/$tdir
6175         local filecount=100
6176         local file1=$dir/f1
6177         local fileN=$dir/f$filecount
6178
6179         rm -rf $dir || error "removing $dir"
6180         test_mkdir -c1 $dir
6181         local mdtidx=$($LFS getstripe -m $dir)
6182         local mdtname=MDT$(printf %04x $mdtidx)
6183         local facet=mds$((mdtidx + 1))
6184
6185         echo "mcreating $filecount files"
6186         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6187
6188         # verify that files do not have EAs yet
6189         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6190                 error "$file1 has an EA"
6191         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6192                 error "$fileN has an EA"
6193
6194         sync
6195         sleep 1
6196         df $dir  #make sure we get new statfs data
6197         local mdsfree=$(do_facet $facet \
6198                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6199         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6200         local file
6201
6202         echo "opening files to create objects/EAs"
6203         for file in $(seq -f $dir/f%g 1 $filecount); do
6204                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6205                         error "opening $file"
6206         done
6207
6208         # verify that files have EAs now
6209         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6210         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6211
6212         sleep 1  #make sure we get new statfs data
6213         df $dir
6214         local mdsfree2=$(do_facet $facet \
6215                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6216         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6217
6218         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6219                 if [ "$mdsfree" != "$mdsfree2" ]; then
6220                         error "MDC before $mdcfree != after $mdcfree2"
6221                 else
6222                         echo "MDC before $mdcfree != after $mdcfree2"
6223                         echo "unable to confirm if MDS has large inodes"
6224                 fi
6225         fi
6226         rm -rf $dir
6227 }
6228 run_test 57b "default LOV EAs are stored inside large inodes ==="
6229
6230 test_58() {
6231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6232         [ -z "$(which wiretest 2>/dev/null)" ] &&
6233                         skip_env "could not find wiretest"
6234
6235         wiretest
6236 }
6237 run_test 58 "verify cross-platform wire constants =============="
6238
6239 test_59() {
6240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6241
6242         echo "touch 130 files"
6243         createmany -o $DIR/f59- 130
6244         echo "rm 130 files"
6245         unlinkmany $DIR/f59- 130
6246         sync
6247         # wait for commitment of removal
6248         wait_delete_completed
6249 }
6250 run_test 59 "verify cancellation of llog records async ========="
6251
6252 TEST60_HEAD="test_60 run $RANDOM"
6253 test_60a() {
6254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6255         remote_mgs_nodsh && skip "remote MGS with nodsh"
6256         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6257                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6258                         skip_env "missing subtest run-llog.sh"
6259
6260         log "$TEST60_HEAD - from kernel mode"
6261         do_facet mgs "$LCTL dk > /dev/null"
6262         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6263         do_facet mgs $LCTL dk > $TMP/$tfile
6264
6265         # LU-6388: test llog_reader
6266         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6267         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6268         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6269                         skip_env "missing llog_reader"
6270         local fstype=$(facet_fstype mgs)
6271         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6272                 skip_env "Only for ldiskfs or zfs type mgs"
6273
6274         local mntpt=$(facet_mntpt mgs)
6275         local mgsdev=$(mgsdevname 1)
6276         local fid_list
6277         local fid
6278         local rec_list
6279         local rec
6280         local rec_type
6281         local obj_file
6282         local path
6283         local seq
6284         local oid
6285         local pass=true
6286
6287         #get fid and record list
6288         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6289                 tail -n 4))
6290         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6291                 tail -n 4))
6292         #remount mgs as ldiskfs or zfs type
6293         stop mgs || error "stop mgs failed"
6294         mount_fstype mgs || error "remount mgs failed"
6295         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6296                 fid=${fid_list[i]}
6297                 rec=${rec_list[i]}
6298                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6299                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6300                 oid=$((16#$oid))
6301
6302                 case $fstype in
6303                         ldiskfs )
6304                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6305                         zfs )
6306                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6307                 esac
6308                 echo "obj_file is $obj_file"
6309                 do_facet mgs $llog_reader $obj_file
6310
6311                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6312                         awk '{ print $3 }' | sed -e "s/^type=//g")
6313                 if [ $rec_type != $rec ]; then
6314                         echo "FAILED test_60a wrong record type $rec_type," \
6315                               "should be $rec"
6316                         pass=false
6317                         break
6318                 fi
6319
6320                 #check obj path if record type is LLOG_LOGID_MAGIC
6321                 if [ "$rec" == "1064553b" ]; then
6322                         path=$(do_facet mgs $llog_reader $obj_file |
6323                                 grep "path=" | awk '{ print $NF }' |
6324                                 sed -e "s/^path=//g")
6325                         if [ $obj_file != $mntpt/$path ]; then
6326                                 echo "FAILED test_60a wrong obj path" \
6327                                       "$montpt/$path, should be $obj_file"
6328                                 pass=false
6329                                 break
6330                         fi
6331                 fi
6332         done
6333         rm -f $TMP/$tfile
6334         #restart mgs before "error", otherwise it will block the next test
6335         stop mgs || error "stop mgs failed"
6336         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6337         $pass || error "test failed, see FAILED test_60a messages for specifics"
6338 }
6339 run_test 60a "llog_test run from kernel module and test llog_reader"
6340
6341 test_60b() { # bug 6411
6342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6343
6344         dmesg > $DIR/$tfile
6345         LLOG_COUNT=$(do_facet mgs dmesg |
6346                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6347                           /llog_[a-z]*.c:[0-9]/ {
6348                                 if (marker)
6349                                         from_marker++
6350                                 from_begin++
6351                           }
6352                           END {
6353                                 if (marker)
6354                                         print from_marker
6355                                 else
6356                                         print from_begin
6357                           }")
6358
6359         [[ $LLOG_COUNT -gt 120 ]] &&
6360                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6361 }
6362 run_test 60b "limit repeated messages from CERROR/CWARN"
6363
6364 test_60c() {
6365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6366
6367         echo "create 5000 files"
6368         createmany -o $DIR/f60c- 5000
6369 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6370         lctl set_param fail_loc=0x80000137
6371         unlinkmany $DIR/f60c- 5000
6372         lctl set_param fail_loc=0
6373 }
6374 run_test 60c "unlink file when mds full"
6375
6376 test_60d() {
6377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6378
6379         SAVEPRINTK=$(lctl get_param -n printk)
6380         # verify "lctl mark" is even working"
6381         MESSAGE="test message ID $RANDOM $$"
6382         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6383         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6384
6385         lctl set_param printk=0 || error "set lnet.printk failed"
6386         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6387         MESSAGE="new test message ID $RANDOM $$"
6388         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6389         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6390         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6391
6392         lctl set_param -n printk="$SAVEPRINTK"
6393 }
6394 run_test 60d "test printk console message masking"
6395
6396 test_60e() {
6397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6398         remote_mds_nodsh && skip "remote MDS with nodsh"
6399
6400         touch $DIR/$tfile
6401 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6402         do_facet mds1 lctl set_param fail_loc=0x15b
6403         rm $DIR/$tfile
6404 }
6405 run_test 60e "no space while new llog is being created"
6406
6407 test_60g() {
6408         local pid
6409
6410         test_mkdir -c $MDSCOUNT $DIR/$tdir
6411         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6412
6413         (
6414                 local index=0
6415                 while true; do
6416                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6417                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6418                         index=$((index + 1))
6419                 done
6420         ) &
6421
6422         pid=$!
6423
6424         for i in $(seq 100); do 
6425                 # define OBD_FAIL_OSD_TXN_START    0x19a
6426                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6427                 usleep 100
6428         done
6429
6430         kill -9 $pid
6431
6432         mkdir $DIR/$tdir/new || error "mkdir failed"
6433         rmdir $DIR/$tdir/new || error "rmdir failed"
6434 }
6435 run_test 60g "transaction abort won't cause MDT hung"
6436
6437 test_61() {
6438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6439
6440         f="$DIR/f61"
6441         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6442         cancel_lru_locks osc
6443         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6444         sync
6445 }
6446 run_test 61 "mmap() writes don't make sync hang ================"
6447
6448 # bug 2330 - insufficient obd_match error checking causes LBUG
6449 test_62() {
6450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6451
6452         f="$DIR/f62"
6453         echo foo > $f
6454         cancel_lru_locks osc
6455         lctl set_param fail_loc=0x405
6456         cat $f && error "cat succeeded, expect -EIO"
6457         lctl set_param fail_loc=0
6458 }
6459 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
6460 # match every page all of the time.
6461 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
6462
6463 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
6464 # Though this test is irrelevant anymore, it helped to reveal some
6465 # other grant bugs (LU-4482), let's keep it.
6466 test_63a() {   # was test_63
6467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6468
6469         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
6470
6471         for i in `seq 10` ; do
6472                 dd if=/dev/zero of=$DIR/f63 bs=8k &
6473                 sleep 5
6474                 kill $!
6475                 sleep 1
6476         done
6477
6478         rm -f $DIR/f63 || true
6479 }
6480 run_test 63a "Verify oig_wait interruption does not crash ======="
6481
6482 # bug 2248 - async write errors didn't return to application on sync
6483 # bug 3677 - async write errors left page locked
6484 test_63b() {
6485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6486
6487         debugsave
6488         lctl set_param debug=-1
6489
6490         # ensure we have a grant to do async writes
6491         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
6492         rm $DIR/$tfile
6493
6494         sync    # sync lest earlier test intercept the fail_loc
6495
6496         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
6497         lctl set_param fail_loc=0x80000406
6498         $MULTIOP $DIR/$tfile Owy && \
6499                 error "sync didn't return ENOMEM"
6500         sync; sleep 2; sync     # do a real sync this time to flush page
6501         lctl get_param -n llite.*.dump_page_cache | grep locked && \
6502                 error "locked page left in cache after async error" || true
6503         debugrestore
6504 }
6505 run_test 63b "async write errors should be returned to fsync ==="
6506
6507 test_64a () {
6508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6509
6510         df $DIR
6511         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
6512 }
6513 run_test 64a "verify filter grant calculations (in kernel) ====="
6514
6515 test_64b () {
6516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6517
6518         sh oos.sh $MOUNT || error "oos.sh failed: $?"
6519 }
6520 run_test 64b "check out-of-space detection on client"
6521
6522 test_64c() {
6523         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
6524 }
6525 run_test 64c "verify grant shrink"
6526
6527 # this does exactly what osc_request.c:osc_announce_cached() does in
6528 # order to calculate max amount of grants to ask from server
6529 want_grant() {
6530         local tgt=$1
6531
6532         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
6533         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
6534
6535         ((rpc_in_flight ++));
6536         nrpages=$((nrpages * rpc_in_flight))
6537
6538         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
6539
6540         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
6541
6542         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
6543         local undirty=$((nrpages * PAGE_SIZE))
6544
6545         local max_extent_pages
6546         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
6547             grep grant_max_extent_size | awk '{print $2}')
6548         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
6549         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
6550         local grant_extent_tax
6551         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6552             grep grant_extent_tax | awk '{print $2}')
6553
6554         undirty=$((undirty + nrextents * grant_extent_tax))
6555
6556         echo $undirty
6557 }
6558
6559 # this is size of unit for grant allocation. It should be equal to
6560 # what tgt_grant.c:tgt_grant_chunk() calculates
6561 grant_chunk() {
6562         local tgt=$1
6563         local max_brw_size
6564         local grant_extent_tax
6565
6566         max_brw_size=$($LCTL get_param osc.${tgt}.import |
6567             grep max_brw_size | awk '{print $2}')
6568
6569         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6570             grep grant_extent_tax | awk '{print $2}')
6571
6572         echo $(((max_brw_size + grant_extent_tax) * 2))
6573 }
6574
6575 test_64d() {
6576         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
6577                 skip "OST < 2.10.55 doesn't limit grants enough"
6578
6579         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
6580         local file=$DIR/$tfile
6581
6582         [[ $($LCTL get_param osc.${tgt}.import |
6583              grep "connect_flags:.*grant_param") ]] ||
6584                 skip "no grant_param connect flag"
6585
6586         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
6587
6588         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
6589
6590         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
6591         stack_trap "rm -f $file" EXIT
6592
6593         $LFS setstripe $file -i 0 -c 1
6594         dd if=/dev/zero of=$file bs=1M count=1000 &
6595         ddpid=$!
6596
6597         while true
6598         do
6599                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
6600                 if [[ $cur_grant -gt $max_cur_granted ]]
6601                 then
6602                         kill $ddpid
6603                         error "cur_grant $cur_grant > $max_cur_granted"
6604                 fi
6605                 kill -0 $ddpid
6606                 [[ $? -ne 0 ]] && break;
6607                 sleep 2
6608         done
6609
6610         rm -f $DIR/$tfile
6611         wait_delete_completed
6612         $LCTL set_param debug="$olddebug" 2> /dev/null || true
6613 }
6614 run_test 64d "check grant limit exceed"
6615
6616 # bug 1414 - set/get directories' stripe info
6617 test_65a() {
6618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6619
6620         test_mkdir $DIR/$tdir
6621         touch $DIR/$tdir/f1
6622         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
6623 }
6624 run_test 65a "directory with no stripe info"
6625
6626 test_65b() {
6627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6628
6629         test_mkdir $DIR/$tdir
6630         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6631
6632         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6633                                                 error "setstripe"
6634         touch $DIR/$tdir/f2
6635         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
6636 }
6637 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
6638
6639 test_65c() {
6640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6641         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
6642
6643         test_mkdir $DIR/$tdir
6644         local stripesize=$($LFS getstripe -S $DIR/$tdir)
6645
6646         $LFS setstripe -S $((stripesize * 4)) -i 1 \
6647                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
6648         touch $DIR/$tdir/f3
6649         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
6650 }
6651 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
6652
6653 test_65d() {
6654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6655
6656         test_mkdir $DIR/$tdir
6657         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
6658         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6659
6660         if [[ $STRIPECOUNT -le 0 ]]; then
6661                 sc=1
6662         elif [[ $STRIPECOUNT -gt 2000 ]]; then
6663 #LOV_MAX_STRIPE_COUNT is 2000
6664                 [[ $OSTCOUNT -gt 2000 ]] && sc=2000 || sc=$(($OSTCOUNT - 1))
6665         else
6666                 sc=$(($STRIPECOUNT - 1))
6667         fi
6668         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
6669         touch $DIR/$tdir/f4 $DIR/$tdir/f5
6670         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
6671                 error "lverify failed"
6672 }
6673 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
6674
6675 test_65e() {
6676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6677
6678         test_mkdir $DIR/$tdir
6679
6680         $LFS setstripe $DIR/$tdir || error "setstripe"
6681         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6682                                         error "no stripe info failed"
6683         touch $DIR/$tdir/f6
6684         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
6685 }
6686 run_test 65e "directory setstripe defaults"
6687
6688 test_65f() {
6689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6690
6691         test_mkdir $DIR/${tdir}f
6692         $RUNAS $LFS setstripe $DIR/${tdir}f &&
6693                 error "setstripe succeeded" || true
6694 }
6695 run_test 65f "dir setstripe permission (should return error) ==="
6696
6697 test_65g() {
6698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6699
6700         test_mkdir $DIR/$tdir
6701         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6702
6703         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6704                 error "setstripe -S failed"
6705         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
6706         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6707                 error "delete default stripe failed"
6708 }
6709 run_test 65g "directory setstripe -d"
6710
6711 test_65h() {
6712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6713
6714         test_mkdir $DIR/$tdir
6715         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6716
6717         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6718                 error "setstripe -S failed"
6719         test_mkdir $DIR/$tdir/dd1
6720         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
6721                 error "stripe info inherit failed"
6722 }
6723 run_test 65h "directory stripe info inherit ===================="
6724
6725 test_65i() {
6726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6727
6728         save_layout_restore_at_exit $MOUNT
6729
6730         # bug6367: set non-default striping on root directory
6731         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
6732
6733         # bug12836: getstripe on -1 default directory striping
6734         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
6735
6736         # bug12836: getstripe -v on -1 default directory striping
6737         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
6738
6739         # bug12836: new find on -1 default directory striping
6740         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
6741 }
6742 run_test 65i "various tests to set root directory striping"
6743
6744 test_65j() { # bug6367
6745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6746
6747         sync; sleep 1
6748
6749         # if we aren't already remounting for each test, do so for this test
6750         if [ "$CLEANUP" = ":" -a "$I_MOUNTED" = "yes" ]; then
6751                 cleanup || error "failed to unmount"
6752                 setup
6753         fi
6754
6755         save_layout_restore_at_exit $MOUNT
6756
6757         $LFS setstripe -d $MOUNT || error "setstripe failed"
6758 }
6759 run_test 65j "set default striping on root directory (bug 6367)="
6760
6761 cleanup_65k() {
6762         rm -rf $DIR/$tdir
6763         wait_delete_completed
6764         do_facet $SINGLEMDS "lctl set_param -n \
6765                 osp.$ost*MDT0000.max_create_count=$max_count"
6766         do_facet $SINGLEMDS "lctl set_param -n \
6767                 osp.$ost*MDT0000.create_count=$count"
6768         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6769         echo $INACTIVE_OSC "is Activate"
6770
6771         wait_osc_import_state mds ost$ostnum FULL
6772 }
6773
6774 test_65k() { # bug11679
6775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6776         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6777         remote_mds_nodsh && skip "remote MDS with nodsh"
6778
6779         local disable_precreate=true
6780         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
6781                 disable_precreate=false
6782
6783         echo "Check OST status: "
6784         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
6785                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
6786
6787         for OSC in $MDS_OSCS; do
6788                 echo $OSC "is active"
6789                 do_facet $SINGLEMDS lctl --device %$OSC activate
6790         done
6791
6792         for INACTIVE_OSC in $MDS_OSCS; do
6793                 local ost=$(osc_to_ost $INACTIVE_OSC)
6794                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
6795                                lov.*md*.target_obd |
6796                                awk -F: /$ost/'{ print $1 }' | head -n 1)
6797
6798                 mkdir -p $DIR/$tdir
6799                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
6800                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
6801
6802                 echo "Deactivate: " $INACTIVE_OSC
6803                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
6804
6805                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
6806                               osp.$ost*MDT0000.create_count")
6807                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
6808                                   osp.$ost*MDT0000.max_create_count")
6809                 $disable_precreate &&
6810                         do_facet $SINGLEMDS "lctl set_param -n \
6811                                 osp.$ost*MDT0000.max_create_count=0"
6812
6813                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
6814                         [ -f $DIR/$tdir/$idx ] && continue
6815                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
6816                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
6817                                 { cleanup_65k;
6818                                   error "setstripe $idx should succeed"; }
6819                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
6820                 done
6821                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
6822                 rmdir $DIR/$tdir
6823
6824                 do_facet $SINGLEMDS "lctl set_param -n \
6825                         osp.$ost*MDT0000.max_create_count=$max_count"
6826                 do_facet $SINGLEMDS "lctl set_param -n \
6827                         osp.$ost*MDT0000.create_count=$count"
6828                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6829                 echo $INACTIVE_OSC "is Activate"
6830
6831                 wait_osc_import_state mds ost$ostnum FULL
6832         done
6833 }
6834 run_test 65k "validate manual striping works properly with deactivated OSCs"
6835
6836 test_65l() { # bug 12836
6837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6838
6839         test_mkdir -p $DIR/$tdir/test_dir
6840         $LFS setstripe -c -1 $DIR/$tdir/test_dir
6841         $LFS find -mtime -1 $DIR/$tdir >/dev/null
6842 }
6843 run_test 65l "lfs find on -1 stripe dir ========================"
6844
6845 test_65m() {
6846         local layout=$(save_layout $MOUNT)
6847         $RUNAS $LFS setstripe -c 2 $MOUNT && {
6848                 restore_layout $MOUNT $layout
6849                 error "setstripe should fail by non-root users"
6850         }
6851         true
6852 }
6853 run_test 65m "normal user can't set filesystem default stripe"
6854
6855 test_65n() {
6856         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
6857         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
6858                 skip "Need MDS version at least 2.12.50"
6859         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
6860
6861         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
6862         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
6863         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
6864
6865         local root_layout=$(save_layout $MOUNT)
6866         stack_trap "restore_layout $MOUNT $root_layout" EXIT
6867
6868         # new subdirectory under root directory should not inherit
6869         # the default layout from root
6870         local dir1=$MOUNT/$tdir-1
6871         mkdir $dir1 || error "mkdir $dir1 failed"
6872         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
6873                 error "$dir1 shouldn't have LOV EA"
6874
6875         # delete the default layout on root directory
6876         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
6877
6878         local dir2=$MOUNT/$tdir-2
6879         mkdir $dir2 || error "mkdir $dir2 failed"
6880         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
6881                 error "$dir2 shouldn't have LOV EA"
6882
6883         # set a new striping pattern on root directory
6884         local def_stripe_size=$($LFS getstripe -S $MOUNT)
6885         local new_def_stripe_size=$((def_stripe_size * 2))
6886         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
6887                 error "set stripe size on $MOUNT failed"
6888
6889         # new file created in $dir2 should inherit the new stripe size from
6890         # the filesystem default
6891         local file2=$dir2/$tfile-2
6892         touch $file2 || error "touch $file2 failed"
6893
6894         local file2_stripe_size=$($LFS getstripe -S $file2)
6895         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
6896                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
6897
6898         local dir3=$MOUNT/$tdir-3
6899         mkdir $dir3 || error "mkdir $dir3 failed"
6900         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
6901                 error "$dir3 shouldn't have LOV EA"
6902
6903         # set OST pool on root directory
6904         local pool=$TESTNAME
6905         pool_add $pool || error "add $pool failed"
6906         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
6907                 error "add targets to $pool failed"
6908
6909         $LFS setstripe -p $pool $MOUNT ||
6910                 error "set OST pool on $MOUNT failed"
6911
6912         # new file created in $dir3 should inherit the pool from
6913         # the filesystem default
6914         local file3=$dir3/$tfile-3
6915         touch $file3 || error "touch $file3 failed"
6916
6917         local file3_pool=$($LFS getstripe -p $file3)
6918         [[ "$file3_pool" = "$pool" ]] ||
6919                 error "$file3 didn't inherit OST pool $pool"
6920
6921         local dir4=$MOUNT/$tdir-4
6922         mkdir $dir4 || error "mkdir $dir4 failed"
6923         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
6924                 error "$dir4 shouldn't have LOV EA"
6925
6926         # new file created in $dir4 should inherit the pool from
6927         # the filesystem default
6928         local file4=$dir4/$tfile-4
6929         touch $file4 || error "touch $file4 failed"
6930
6931         local file4_pool=$($LFS getstripe -p $file4)
6932         [[ "$file4_pool" = "$pool" ]] ||
6933                 error "$file4 didn't inherit OST pool $pool"
6934
6935         # new subdirectory under non-root directory should inherit
6936         # the default layout from its parent directory
6937         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
6938                 error "set directory layout on $dir4 failed"
6939
6940         local dir5=$dir4/$tdir-5
6941         mkdir $dir5 || error "mkdir $dir5 failed"
6942
6943         local dir4_layout=$(get_layout_param $dir4)
6944         local dir5_layout=$(get_layout_param $dir5)
6945         [[ "$dir4_layout" = "$dir5_layout" ]] ||
6946                 error "$dir5 should inherit the default layout from $dir4"
6947 }
6948 run_test 65n "don't inherit default layout from root for new subdirectories"
6949
6950 # bug 2543 - update blocks count on client
6951 test_66() {
6952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6953
6954         COUNT=${COUNT:-8}
6955         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
6956         sync; sync_all_data; sync; sync_all_data
6957         cancel_lru_locks osc
6958         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
6959         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
6960 }
6961 run_test 66 "update inode blocks count on client ==============="
6962
6963 meminfo() {
6964         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
6965 }
6966
6967 swap_used() {
6968         swapon -s | awk '($1 == "'$1'") { print $4 }'
6969 }
6970
6971 # bug5265, obdfilter oa2dentry return -ENOENT
6972 # #define OBD_FAIL_SRV_ENOENT 0x217
6973 test_69() {
6974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6975         remote_ost_nodsh && skip "remote OST with nodsh"
6976
6977         f="$DIR/$tfile"
6978         $LFS setstripe -c 1 -i 0 $f
6979
6980         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
6981
6982         do_facet ost1 lctl set_param fail_loc=0x217
6983         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
6984         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
6985
6986         do_facet ost1 lctl set_param fail_loc=0
6987         $DIRECTIO write $f 0 2 || error "write error"
6988
6989         cancel_lru_locks osc
6990         $DIRECTIO read $f 0 1 || error "read error"
6991
6992         do_facet ost1 lctl set_param fail_loc=0x217
6993         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
6994
6995         do_facet ost1 lctl set_param fail_loc=0
6996         rm -f $f
6997 }
6998 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
6999
7000 test_71() {
7001         test_mkdir $DIR/$tdir
7002         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7003         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7004 }
7005 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7006
7007 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7009         [ "$RUNAS_ID" = "$UID" ] &&
7010                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7011         # Check that testing environment is properly set up. Skip if not
7012         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7013                 skip_env "User $RUNAS_ID does not exist - skipping"
7014
7015         touch $DIR/$tfile
7016         chmod 777 $DIR/$tfile
7017         chmod ug+s $DIR/$tfile
7018         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7019                 error "$RUNAS dd $DIR/$tfile failed"
7020         # See if we are still setuid/sgid
7021         test -u $DIR/$tfile -o -g $DIR/$tfile &&
7022                 error "S/gid is not dropped on write"
7023         # Now test that MDS is updated too
7024         cancel_lru_locks mdc
7025         test -u $DIR/$tfile -o -g $DIR/$tfile &&
7026                 error "S/gid is not dropped on MDS"
7027         rm -f $DIR/$tfile
7028 }
7029 run_test 72a "Test that remove suid works properly (bug5695) ===="
7030
7031 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7032         local perm
7033
7034         [ "$RUNAS_ID" = "$UID" ] &&
7035                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7036         [ "$RUNAS_ID" -eq 0 ] &&
7037                 skip_env "RUNAS_ID = 0 -- skipping"
7038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7039         # Check that testing environment is properly set up. Skip if not
7040         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7041                 skip_env "User $RUNAS_ID does not exist - skipping"
7042
7043         touch $DIR/${tfile}-f{g,u}
7044         test_mkdir $DIR/${tfile}-dg
7045         test_mkdir $DIR/${tfile}-du
7046         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7047         chmod g+s $DIR/${tfile}-{f,d}g
7048         chmod u+s $DIR/${tfile}-{f,d}u
7049         for perm in 777 2777 4777; do
7050                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7051                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7052                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7053                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7054         done
7055         true
7056 }
7057 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7058
7059 # bug 3462 - multiple simultaneous MDC requests
7060 test_73() {
7061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7062
7063         test_mkdir $DIR/d73-1
7064         test_mkdir $DIR/d73-2
7065         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7066         pid1=$!
7067
7068         lctl set_param fail_loc=0x80000129
7069         $MULTIOP $DIR/d73-1/f73-2 Oc &
7070         sleep 1
7071         lctl set_param fail_loc=0
7072
7073         $MULTIOP $DIR/d73-2/f73-3 Oc &
7074         pid3=$!
7075
7076         kill -USR1 $pid1
7077         wait $pid1 || return 1
7078
7079         sleep 25
7080
7081         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7082         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7083         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7084
7085         rm -rf $DIR/d73-*
7086 }
7087 run_test 73 "multiple MDC requests (should not deadlock)"
7088
7089 test_74a() { # bug 6149, 6184
7090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7091
7092         touch $DIR/f74a
7093         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7094         #
7095         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7096         # will spin in a tight reconnection loop
7097         $LCTL set_param fail_loc=0x8000030e
7098         # get any lock that won't be difficult - lookup works.
7099         ls $DIR/f74a
7100         $LCTL set_param fail_loc=0
7101         rm -f $DIR/f74a
7102         true
7103 }
7104 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7105
7106 test_74b() { # bug 13310
7107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7108
7109         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7110         #
7111         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7112         # will spin in a tight reconnection loop
7113         $LCTL set_param fail_loc=0x8000030e
7114         # get a "difficult" lock
7115         touch $DIR/f74b
7116         $LCTL set_param fail_loc=0
7117         rm -f $DIR/f74b
7118         true
7119 }
7120 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7121
7122 test_74c() {
7123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7124
7125         #define OBD_FAIL_LDLM_NEW_LOCK
7126         $LCTL set_param fail_loc=0x319
7127         touch $DIR/$tfile && error "touch successful"
7128         $LCTL set_param fail_loc=0
7129         true
7130 }
7131 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7132
7133 num_inodes() {
7134         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7135 }
7136
7137 test_76() { # Now for bug 20433, added originally in bug 1443
7138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7139
7140         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7141
7142         cancel_lru_locks osc
7143         BEFORE_INODES=$(num_inodes)
7144         echo "before inodes: $BEFORE_INODES"
7145         local COUNT=1000
7146         [ "$SLOW" = "no" ] && COUNT=100
7147         for i in $(seq $COUNT); do
7148                 touch $DIR/$tfile
7149                 rm -f $DIR/$tfile
7150         done
7151         cancel_lru_locks osc
7152         AFTER_INODES=$(num_inodes)
7153         echo "after inodes: $AFTER_INODES"
7154         local wait=0
7155         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7156                 sleep 2
7157                 AFTER_INODES=$(num_inodes)
7158                 wait=$((wait+2))
7159                 echo "wait $wait seconds inodes: $AFTER_INODES"
7160                 if [ $wait -gt 30 ]; then
7161                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7162                 fi
7163         done
7164 }
7165 run_test 76 "confirm clients recycle inodes properly ===="
7166
7167
7168 export ORIG_CSUM=""
7169 set_checksums()
7170 {
7171         # Note: in sptlrpc modes which enable its own bulk checksum, the
7172         # original crc32_le bulk checksum will be automatically disabled,
7173         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7174         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7175         # In this case set_checksums() will not be no-op, because sptlrpc
7176         # bulk checksum will be enabled all through the test.
7177
7178         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7179         lctl set_param -n osc.*.checksums $1
7180         return 0
7181 }
7182
7183 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7184                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7185 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7186                              tr -d [] | head -n1)}
7187 set_checksum_type()
7188 {
7189         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7190         log "set checksum type to $1"
7191         return 0
7192 }
7193 F77_TMP=$TMP/f77-temp
7194 F77SZ=8
7195 setup_f77() {
7196         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7197                 error "error writing to $F77_TMP"
7198 }
7199
7200 test_77a() { # bug 10889
7201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7202         $GSS && skip_env "could not run with gss"
7203
7204         [ ! -f $F77_TMP ] && setup_f77
7205         set_checksums 1
7206         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7207         set_checksums 0
7208         rm -f $DIR/$tfile
7209 }
7210 run_test 77a "normal checksum read/write operation"
7211
7212 test_77b() { # bug 10889
7213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7214         $GSS && skip_env "could not run with gss"
7215
7216         [ ! -f $F77_TMP ] && setup_f77
7217         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7218         $LCTL set_param fail_loc=0x80000409
7219         set_checksums 1
7220
7221         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7222                 error "dd error: $?"
7223         $LCTL set_param fail_loc=0
7224
7225         for algo in $CKSUM_TYPES; do
7226                 cancel_lru_locks osc
7227                 set_checksum_type $algo
7228                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7229                 $LCTL set_param fail_loc=0x80000408
7230                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7231                 $LCTL set_param fail_loc=0
7232         done
7233         set_checksums 0
7234         set_checksum_type $ORIG_CSUM_TYPE
7235         rm -f $DIR/$tfile
7236 }
7237 run_test 77b "checksum error on client write, read"
7238
7239 cleanup_77c() {
7240         trap 0
7241         set_checksums 0
7242         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7243         $check_ost &&
7244                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7245         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7246         $check_ost && [ -n "$ost_file_prefix" ] &&
7247                 do_facet ost1 rm -f ${ost_file_prefix}\*
7248 }
7249
7250 test_77c() {
7251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7252         $GSS && skip_env "could not run with gss"
7253         remote_ost_nodsh && skip "remote OST with nodsh"
7254
7255         local bad1
7256         local osc_file_prefix
7257         local osc_file
7258         local check_ost=false
7259         local ost_file_prefix
7260         local ost_file
7261         local orig_cksum
7262         local dump_cksum
7263         local fid
7264
7265         # ensure corruption will occur on first OSS/OST
7266         $LFS setstripe -i 0 $DIR/$tfile
7267
7268         [ ! -f $F77_TMP ] && setup_f77
7269         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7270                 error "dd write error: $?"
7271         fid=$($LFS path2fid $DIR/$tfile)
7272
7273         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7274         then
7275                 check_ost=true
7276                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7277                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7278         else
7279                 echo "OSS do not support bulk pages dump upon error"
7280         fi
7281
7282         osc_file_prefix=$($LCTL get_param -n debug_path)
7283         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7284
7285         trap cleanup_77c EXIT
7286
7287         set_checksums 1
7288         # enable bulk pages dump upon error on Client
7289         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7290         # enable bulk pages dump upon error on OSS
7291         $check_ost &&
7292                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7293
7294         # flush Client cache to allow next read to reach OSS
7295         cancel_lru_locks osc
7296
7297         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7298         $LCTL set_param fail_loc=0x80000408
7299         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7300         $LCTL set_param fail_loc=0
7301
7302         rm -f $DIR/$tfile
7303
7304         # check cksum dump on Client
7305         osc_file=$(ls ${osc_file_prefix}*)
7306         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7307         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7308         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7309         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7310         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7311                      cksum)
7312         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7313         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7314                 error "dump content does not match on Client"
7315
7316         $check_ost || skip "No need to check cksum dump on OSS"
7317
7318         # check cksum dump on OSS
7319         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7320         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7321         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7322         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7323         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7324                 error "dump content does not match on OSS"
7325
7326         cleanup_77c
7327 }
7328 run_test 77c "checksum error on client read with debug"
7329
7330 test_77d() { # bug 10889
7331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7332         $GSS && skip_env "could not run with gss"
7333
7334         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7335         $LCTL set_param fail_loc=0x80000409
7336         set_checksums 1
7337         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7338                 error "direct write: rc=$?"
7339         $LCTL set_param fail_loc=0
7340         set_checksums 0
7341
7342         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7343         $LCTL set_param fail_loc=0x80000408
7344         set_checksums 1
7345         cancel_lru_locks osc
7346         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7347                 error "direct read: rc=$?"
7348         $LCTL set_param fail_loc=0
7349         set_checksums 0
7350 }
7351 run_test 77d "checksum error on OST direct write, read"
7352
7353 test_77f() { # bug 10889
7354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7355         $GSS && skip_env "could not run with gss"
7356
7357         set_checksums 1
7358         for algo in $CKSUM_TYPES; do
7359                 cancel_lru_locks osc
7360                 set_checksum_type $algo
7361                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7362                 $LCTL set_param fail_loc=0x409
7363                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7364                         error "direct write succeeded"
7365                 $LCTL set_param fail_loc=0
7366         done
7367         set_checksum_type $ORIG_CSUM_TYPE
7368         set_checksums 0
7369 }
7370 run_test 77f "repeat checksum error on write (expect error)"
7371
7372 test_77g() { # bug 10889
7373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7374         $GSS && skip_env "could not run with gss"
7375         remote_ost_nodsh && skip "remote OST with nodsh"
7376
7377         [ ! -f $F77_TMP ] && setup_f77
7378
7379         local file=$DIR/$tfile
7380         stack_trap "rm -f $file" EXIT
7381
7382         $LFS setstripe -c 1 -i 0 $file
7383         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7384         do_facet ost1 lctl set_param fail_loc=0x8000021a
7385         set_checksums 1
7386         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7387                 error "write error: rc=$?"
7388         do_facet ost1 lctl set_param fail_loc=0
7389         set_checksums 0
7390
7391         cancel_lru_locks osc
7392         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7393         do_facet ost1 lctl set_param fail_loc=0x8000021b
7394         set_checksums 1
7395         cmp $F77_TMP $file || error "file compare failed"
7396         do_facet ost1 lctl set_param fail_loc=0
7397         set_checksums 0
7398 }
7399 run_test 77g "checksum error on OST write, read"
7400
7401 test_77k() { # LU-10906
7402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7403         $GSS && skip_env "could not run with gss"
7404
7405         local cksum_param="osc.$FSNAME*.checksums"
7406         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7407         local checksum
7408         local i
7409
7410         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7411         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7412         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7413                 EXIT
7414
7415         for i in 0 1; do
7416                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7417                         error "failed to set checksum=$i on MGS"
7418                 wait_update $HOSTNAME "$get_checksum" $i
7419                 #remount
7420                 echo "remount client, checksum should be $i"
7421                 remount_client $MOUNT || "failed to remount client"
7422                 checksum=$(eval $get_checksum)
7423                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7424         done
7425         # remove persistent param to avoid races with checksum mountopt below
7426         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7427                 error "failed to delete checksum on MGS"
7428
7429         for opt in "checksum" "nochecksum"; do
7430                 #remount with mount option
7431                 echo "remount client with option $opt, checksum should be $i"
7432                 umount_client $MOUNT || "failed to umount client"
7433                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7434                         "failed to mount client with option '$opt'"
7435                 checksum=$(eval $get_checksum)
7436                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7437                 i=$((i - 1))
7438         done
7439
7440         remount_client $MOUNT || "failed to remount client"
7441 }
7442 run_test 77k "enable/disable checksum correctly"
7443
7444 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7445 rm -f $F77_TMP
7446 unset F77_TMP
7447
7448 cleanup_test_78() {
7449         trap 0
7450         rm -f $DIR/$tfile
7451 }
7452
7453 test_78() { # bug 10901
7454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7455         remote_ost || skip_env "local OST"
7456
7457         NSEQ=5
7458         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
7459         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
7460         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
7461         echo "MemTotal: $MEMTOTAL"
7462
7463         # reserve 256MB of memory for the kernel and other running processes,
7464         # and then take 1/2 of the remaining memory for the read/write buffers.
7465         if [ $MEMTOTAL -gt 512 ] ;then
7466                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
7467         else
7468                 # for those poor memory-starved high-end clusters...
7469                 MEMTOTAL=$((MEMTOTAL / 2))
7470         fi
7471         echo "Mem to use for directio: $MEMTOTAL"
7472
7473         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
7474         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
7475         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
7476         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
7477                 head -n1)
7478         echo "Smallest OST: $SMALLESTOST"
7479         [[ $SMALLESTOST -lt 10240 ]] &&
7480                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
7481
7482         trap cleanup_test_78 EXIT
7483
7484         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
7485                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
7486
7487         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
7488         echo "File size: $F78SIZE"
7489         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
7490         for i in $(seq 1 $NSEQ); do
7491                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
7492                 echo directIO rdwr round $i of $NSEQ
7493                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
7494         done
7495
7496         cleanup_test_78
7497 }
7498 run_test 78 "handle large O_DIRECT writes correctly ============"
7499
7500 test_79() { # bug 12743
7501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7502
7503         wait_delete_completed
7504
7505         BKTOTAL=$(calc_osc_kbytes kbytestotal)
7506         BKFREE=$(calc_osc_kbytes kbytesfree)
7507         BKAVAIL=$(calc_osc_kbytes kbytesavail)
7508
7509         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
7510         DFTOTAL=`echo $STRING | cut -d, -f1`
7511         DFUSED=`echo $STRING  | cut -d, -f2`
7512         DFAVAIL=`echo $STRING | cut -d, -f3`
7513         DFFREE=$(($DFTOTAL - $DFUSED))
7514
7515         ALLOWANCE=$((64 * $OSTCOUNT))
7516
7517         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
7518            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
7519                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
7520         fi
7521         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
7522            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
7523                 error "df free($DFFREE) mismatch OST free($BKFREE)"
7524         fi
7525         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
7526            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
7527                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
7528         fi
7529 }
7530 run_test 79 "df report consistency check ======================="
7531
7532 test_80() { # bug 10718
7533         remote_ost_nodsh && skip "remote OST with nodsh"
7534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7535
7536         # relax strong synchronous semantics for slow backends like ZFS
7537         local soc="obdfilter.*.sync_on_lock_cancel"
7538         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
7539         local hosts=
7540         if [ "$soc_old" != "never" ] &&
7541                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
7542                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
7543                                 facet_active_host $host; done | sort -u)
7544                         do_nodes $hosts lctl set_param $soc=never
7545         fi
7546
7547         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
7548         sync; sleep 1; sync
7549         local BEFORE=`date +%s`
7550         cancel_lru_locks osc
7551         local AFTER=`date +%s`
7552         local DIFF=$((AFTER-BEFORE))
7553         if [ $DIFF -gt 1 ] ; then
7554                 error "elapsed for 1M@1T = $DIFF"
7555         fi
7556
7557         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
7558
7559         rm -f $DIR/$tfile
7560 }
7561 run_test 80 "Page eviction is equally fast at high offsets too  ===="
7562
7563 test_81a() { # LU-456
7564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7565         remote_ost_nodsh && skip "remote OST with nodsh"
7566
7567         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7568         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
7569         do_facet ost1 lctl set_param fail_loc=0x80000228
7570
7571         # write should trigger a retry and success
7572         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7573         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7574         RC=$?
7575         if [ $RC -ne 0 ] ; then
7576                 error "write should success, but failed for $RC"
7577         fi
7578 }
7579 run_test 81a "OST should retry write when get -ENOSPC ==============="
7580
7581 test_81b() { # LU-456
7582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7583         remote_ost_nodsh && skip "remote OST with nodsh"
7584
7585         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7586         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
7587         do_facet ost1 lctl set_param fail_loc=0x228
7588
7589         # write should retry several times and return -ENOSPC finally
7590         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7591         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7592         RC=$?
7593         ENOSPC=28
7594         if [ $RC -ne $ENOSPC ] ; then
7595                 error "dd should fail for -ENOSPC, but succeed."
7596         fi
7597 }
7598 run_test 81b "OST should return -ENOSPC when retry still fails ======="
7599
7600 test_82() { # LU-1031
7601         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
7602         local gid1=14091995
7603         local gid2=16022000
7604
7605         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
7606         local MULTIPID1=$!
7607         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
7608         local MULTIPID2=$!
7609         kill -USR1 $MULTIPID2
7610         sleep 2
7611         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
7612                 error "First grouplock does not block second one"
7613         else
7614                 echo "Second grouplock blocks first one"
7615         fi
7616         kill -USR1 $MULTIPID1
7617         wait $MULTIPID1
7618         wait $MULTIPID2
7619 }
7620 run_test 82 "Basic grouplock test"
7621
7622 test_99() {
7623         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
7624
7625         test_mkdir $DIR/$tdir.cvsroot
7626         chown $RUNAS_ID $DIR/$tdir.cvsroot
7627
7628         cd $TMP
7629         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
7630
7631         cd /etc/init.d
7632         # some versions of cvs import exit(1) when asked to import links or
7633         # files they can't read.  ignore those files.
7634         local toignore=$(find . -type l -printf '-I %f\n' -o \
7635                          ! -perm /4 -printf '-I %f\n')
7636         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
7637                 $tdir.reposname vtag rtag
7638
7639         cd $DIR
7640         test_mkdir $DIR/$tdir.reposname
7641         chown $RUNAS_ID $DIR/$tdir.reposname
7642         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
7643
7644         cd $DIR/$tdir.reposname
7645         $RUNAS touch foo99
7646         $RUNAS cvs add -m 'addmsg' foo99
7647         $RUNAS cvs update
7648         $RUNAS cvs commit -m 'nomsg' foo99
7649         rm -fr $DIR/$tdir.cvsroot
7650 }
7651 run_test 99 "cvs strange file/directory operations"
7652
7653 test_100() {
7654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7655         [[ "$NETTYPE" =~ tcp ]] ||
7656                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
7657         remote_ost_nodsh && skip "remote OST with nodsh"
7658         remote_mds_nodsh && skip "remote MDS with nodsh"
7659         remote_servers ||
7660                 skip "useless for local single node setup"
7661
7662         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
7663                 [ "$PROT" != "tcp" ] && continue
7664                 RPORT=$(echo $REMOTE | cut -d: -f2)
7665                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
7666
7667                 rc=0
7668                 LPORT=`echo $LOCAL | cut -d: -f2`
7669                 if [ $LPORT -ge 1024 ]; then
7670                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
7671                         netstat -tna
7672                         error_exit "local: $LPORT > 1024, remote: $RPORT"
7673                 fi
7674         done
7675         [ "$rc" = 0 ] || error_exit "privileged port not found" )
7676 }
7677 run_test 100 "check local port using privileged port ==========="
7678
7679 function get_named_value()
7680 {
7681     local tag
7682
7683     tag=$1
7684     while read ;do
7685         line=$REPLY
7686         case $line in
7687         $tag*)
7688             echo $line | sed "s/^$tag[ ]*//"
7689             break
7690             ;;
7691         esac
7692     done
7693 }
7694
7695 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
7696                    awk '/^max_cached_mb/ { print $2 }')
7697
7698 cleanup_101a() {
7699         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
7700         trap 0
7701 }
7702
7703 test_101a() {
7704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7705         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
7706
7707         local s
7708         local discard
7709         local nreads=10000
7710         local cache_limit=32
7711
7712         $LCTL set_param -n osc.*-osc*.rpc_stats 0
7713         trap cleanup_101a EXIT
7714         $LCTL set_param -n llite.*.read_ahead_stats 0
7715         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
7716
7717         #
7718         # randomly read 10000 of 64K chunks from file 3x 32MB in size
7719         #
7720         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
7721         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
7722
7723         discard=0
7724         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
7725                 get_named_value 'read but discarded' | cut -d" " -f1); do
7726                         discard=$(($discard + $s))
7727         done
7728         cleanup_101a
7729
7730         if [[ $(($discard * 10)) -gt $nreads ]]; then
7731                 $LCTL get_param osc.*-osc*.rpc_stats
7732                 $LCTL get_param llite.*.read_ahead_stats
7733                 error "too many ($discard) discarded pages"
7734         fi
7735         rm -f $DIR/$tfile || true
7736 }
7737 run_test 101a "check read-ahead for random reads"
7738
7739 setup_test101bc() {
7740         test_mkdir $DIR/$tdir
7741         local ssize=$1
7742         local FILE_LENGTH=$2
7743         STRIPE_OFFSET=0
7744
7745         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
7746
7747         local list=$(comma_list $(osts_nodes))
7748         set_osd_param $list '' read_cache_enable 0
7749         set_osd_param $list '' writethrough_cache_enable 0
7750
7751         trap cleanup_test101bc EXIT
7752         # prepare the read-ahead file
7753         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
7754
7755         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
7756                                 count=$FILE_SIZE_MB 2> /dev/null
7757
7758 }
7759
7760 cleanup_test101bc() {
7761         trap 0
7762         rm -rf $DIR/$tdir
7763         rm -f $DIR/$tfile
7764
7765         local list=$(comma_list $(osts_nodes))
7766         set_osd_param $list '' read_cache_enable 1
7767         set_osd_param $list '' writethrough_cache_enable 1
7768 }
7769
7770 calc_total() {
7771         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
7772 }
7773
7774 ra_check_101() {
7775         local READ_SIZE=$1
7776         local STRIPE_SIZE=$2
7777         local FILE_LENGTH=$3
7778         local RA_INC=1048576
7779         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
7780         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
7781                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
7782         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
7783                         get_named_value 'read but discarded' |
7784                         cut -d" " -f1 | calc_total)
7785         if [[ $DISCARD -gt $discard_limit ]]; then
7786                 $LCTL get_param llite.*.read_ahead_stats
7787                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
7788         else
7789                 echo "Read-ahead success for size ${READ_SIZE}"
7790         fi
7791 }
7792
7793 test_101b() {
7794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7795         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7796
7797         local STRIPE_SIZE=1048576
7798         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
7799
7800         if [ $SLOW == "yes" ]; then
7801                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
7802         else
7803                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
7804         fi
7805
7806         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
7807
7808         # prepare the read-ahead file
7809         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7810         cancel_lru_locks osc
7811         for BIDX in 2 4 8 16 32 64 128 256
7812         do
7813                 local BSIZE=$((BIDX*4096))
7814                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
7815                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
7816                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
7817                 $LCTL set_param -n llite.*.read_ahead_stats 0
7818                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
7819                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
7820                 cancel_lru_locks osc
7821                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
7822         done
7823         cleanup_test101bc
7824         true
7825 }
7826 run_test 101b "check stride-io mode read-ahead ================="
7827
7828 test_101c() {
7829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7830
7831         local STRIPE_SIZE=1048576
7832         local FILE_LENGTH=$((STRIPE_SIZE*100))
7833         local nreads=10000
7834         local rsize=65536
7835         local osc_rpc_stats
7836
7837         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7838
7839         cancel_lru_locks osc
7840         $LCTL set_param osc.*.rpc_stats 0
7841         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
7842         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
7843                 local stats=$($LCTL get_param -n $osc_rpc_stats)
7844                 local lines=$(echo "$stats" | awk 'END {print NR;}')
7845                 local size
7846
7847                 if [ $lines -le 20 ]; then
7848                         continue
7849                 fi
7850                 for size in 1 2 4 8; do
7851                         local rpc=$(echo "$stats" |
7852                                     awk '($1 == "'$size':") {print $2; exit; }')
7853                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
7854                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
7855                 done
7856                 echo "$osc_rpc_stats check passed!"
7857         done
7858         cleanup_test101bc
7859         true
7860 }
7861 run_test 101c "check stripe_size aligned read-ahead ================="
7862
7863 set_read_ahead() {
7864         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
7865         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
7866 }
7867
7868 test_101d() {
7869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7870
7871         local file=$DIR/$tfile
7872         local sz_MB=${FILESIZE_101d:-500}
7873         local ra_MB=${READAHEAD_MB:-40}
7874
7875         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
7876         [ $free_MB -lt $sz_MB ] &&
7877                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
7878
7879         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
7880         $LFS setstripe -c -1 $file || error "setstripe failed"
7881
7882         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
7883         echo Cancel LRU locks on lustre client to flush the client cache
7884         cancel_lru_locks osc
7885
7886         echo Disable read-ahead
7887         local old_READAHEAD=$(set_read_ahead 0)
7888
7889         echo Reading the test file $file with read-ahead disabled
7890         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7891
7892         echo Cancel LRU locks on lustre client to flush the client cache
7893         cancel_lru_locks osc
7894         echo Enable read-ahead with ${ra_MB}MB
7895         set_read_ahead $ra_MB
7896
7897         echo Reading the test file $file with read-ahead enabled
7898         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7899
7900         echo "read-ahead disabled time read $raOFF"
7901         echo "read-ahead enabled  time read $raON"
7902
7903         set_read_ahead $old_READAHEAD
7904         rm -f $file
7905         wait_delete_completed
7906
7907         [ $raOFF -le 1 -o $raON -lt $raOFF ] ||
7908                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
7909 }
7910 run_test 101d "file read with and without read-ahead enabled"
7911
7912 test_101e() {
7913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7914
7915         local file=$DIR/$tfile
7916         local size_KB=500  #KB
7917         local count=100
7918         local bsize=1024
7919
7920         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
7921         local need_KB=$((count * size_KB))
7922         [[ $free_KB -le $need_KB ]] &&
7923                 skip_env "Need free space $need_KB, have $free_KB"
7924
7925         echo "Creating $count ${size_KB}K test files"
7926         for ((i = 0; i < $count; i++)); do
7927                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
7928         done
7929
7930         echo "Cancel LRU locks on lustre client to flush the client cache"
7931         cancel_lru_locks $OSC
7932
7933         echo "Reset readahead stats"
7934         $LCTL set_param -n llite.*.read_ahead_stats 0
7935
7936         for ((i = 0; i < $count; i++)); do
7937                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
7938         done
7939
7940         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
7941                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
7942
7943         for ((i = 0; i < $count; i++)); do
7944                 rm -rf $file.$i 2>/dev/null
7945         done
7946
7947         #10000 means 20% reads are missing in readahead
7948         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
7949 }
7950 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
7951
7952 test_101f() {
7953         which iozone || skip_env "no iozone installed"
7954
7955         local old_debug=$($LCTL get_param debug)
7956         old_debug=${old_debug#*=}
7957         $LCTL set_param debug="reada mmap"
7958
7959         # create a test file
7960         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
7961
7962         echo Cancel LRU locks on lustre client to flush the client cache
7963         cancel_lru_locks osc
7964
7965         echo Reset readahead stats
7966         $LCTL set_param -n llite.*.read_ahead_stats 0
7967
7968         echo mmap read the file with small block size
7969         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
7970                 > /dev/null 2>&1
7971
7972         echo checking missing pages
7973         $LCTL get_param llite.*.read_ahead_stats
7974         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
7975                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
7976
7977         $LCTL set_param debug="$old_debug"
7978         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
7979         rm -f $DIR/$tfile
7980 }
7981 run_test 101f "check mmap read performance"
7982
7983 test_101g_brw_size_test() {
7984         local mb=$1
7985         local pages=$((mb * 1048576 / PAGE_SIZE))
7986         local file=$DIR/$tfile
7987
7988         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
7989                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
7990         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
7991                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
7992                         return 2
7993         done
7994
7995         stack_trap "rm -f $file" EXIT
7996         $LCTL set_param -n osc.*.rpc_stats=0
7997
7998         # 10 RPCs should be enough for the test
7999         local count=10
8000         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8001                 { error "dd write ${mb} MB blocks failed"; return 3; }
8002         cancel_lru_locks osc
8003         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8004                 { error "dd write ${mb} MB blocks failed"; return 4; }
8005
8006         # calculate number of full-sized read and write RPCs
8007         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8008                 sed -n '/pages per rpc/,/^$/p' |
8009                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8010                 END { print reads,writes }'))
8011         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8012                 return 5
8013         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8014                 return 6
8015
8016         return 0
8017 }
8018
8019 test_101g() {
8020         remote_ost_nodsh && skip "remote OST with nodsh"
8021
8022         local rpcs
8023         local osts=$(get_facets OST)
8024         local list=$(comma_list $(osts_nodes))
8025         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8026         local brw_size="obdfilter.*.brw_size"
8027
8028         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8029
8030         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8031         if [ $OST1_VERSION -ge $(version_code 2.8.52) -o \
8032              \( $OST1_VERSION -ge $(version_code 2.7.17) -a \
8033                 $OST1_VERSION -lt $(version_code 2.7.50) \) ] &&
8034            [ $CLIENT_VERSION -ge $(version_code 2.8.52) -o \
8035              \( $CLIENT_VERSION -ge $(version_code 2.7.17) -a \
8036                 $CLIENT_VERSION -lt $(version_code 2.7.50) \) ]; then
8037                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] && suffix="M"
8038                 if [[ $orig_mb -lt 16 ]]; then
8039                         save_lustre_params $osts "$brw_size" > $p
8040                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8041                                 error "set 16MB RPC size failed"
8042
8043                         echo "remount client to enable new RPC size"
8044                         remount_client $MOUNT || error "remount_client failed"
8045                 fi
8046
8047                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8048                 # should be able to set brw_size=12, but no rpc_stats for that
8049                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8050         fi
8051
8052         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8053
8054         if [[ $orig_mb -lt 16 ]]; then
8055                 restore_lustre_params < $p
8056                 remount_client $MOUNT || error "remount_client restore failed"
8057         fi
8058
8059         rm -f $p $DIR/$tfile
8060 }
8061 run_test 101g "Big bulk(4/16 MiB) readahead"
8062
8063 setup_test102() {
8064         test_mkdir $DIR/$tdir
8065         chown $RUNAS_ID $DIR/$tdir
8066         STRIPE_SIZE=65536
8067         STRIPE_OFFSET=1
8068         STRIPE_COUNT=$OSTCOUNT
8069         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8070
8071         trap cleanup_test102 EXIT
8072         cd $DIR
8073         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8074         cd $DIR/$tdir
8075         for num in 1 2 3 4; do
8076                 for count in $(seq 1 $STRIPE_COUNT); do
8077                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8078                                 local size=`expr $STRIPE_SIZE \* $num`
8079                                 local file=file"$num-$idx-$count"
8080                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8081                         done
8082                 done
8083         done
8084
8085         cd $DIR
8086         $1 tar cf $TMP/f102.tar $tdir --xattrs
8087 }
8088
8089 cleanup_test102() {
8090         trap 0
8091         rm -f $TMP/f102.tar
8092         rm -rf $DIR/d0.sanity/d102
8093 }
8094
8095 test_102a() {
8096         [ "$UID" != 0 ] && skip "must run as root"
8097         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8098                 skip_env "must have user_xattr"
8099
8100         [ -z "$(which setfattr 2>/dev/null)" ] &&
8101                 skip_env "could not find setfattr"
8102
8103         local testfile=$DIR/$tfile
8104
8105         touch $testfile
8106         echo "set/get xattr..."
8107         setfattr -n trusted.name1 -v value1 $testfile ||
8108                 error "setfattr -n trusted.name1=value1 $testfile failed"
8109         getfattr -n trusted.name1 $testfile 2> /dev/null |
8110           grep "trusted.name1=.value1" ||
8111                 error "$testfile missing trusted.name1=value1"
8112
8113         setfattr -n user.author1 -v author1 $testfile ||
8114                 error "setfattr -n user.author1=author1 $testfile failed"
8115         getfattr -n user.author1 $testfile 2> /dev/null |
8116           grep "user.author1=.author1" ||
8117                 error "$testfile missing trusted.author1=author1"
8118
8119         echo "listxattr..."
8120         setfattr -n trusted.name2 -v value2 $testfile ||
8121                 error "$testfile unable to set trusted.name2"
8122         setfattr -n trusted.name3 -v value3 $testfile ||
8123                 error "$testfile unable to set trusted.name3"
8124         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8125             grep "trusted.name" | wc -l) -eq 3 ] ||
8126                 error "$testfile missing 3 trusted.name xattrs"
8127
8128         setfattr -n user.author2 -v author2 $testfile ||
8129                 error "$testfile unable to set user.author2"
8130         setfattr -n user.author3 -v author3 $testfile ||
8131                 error "$testfile unable to set user.author3"
8132         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8133             grep "user.author" | wc -l) -eq 3 ] ||
8134                 error "$testfile missing 3 user.author xattrs"
8135
8136         echo "remove xattr..."
8137         setfattr -x trusted.name1 $testfile ||
8138                 error "$testfile error deleting trusted.name1"
8139         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8140                 error "$testfile did not delete trusted.name1 xattr"
8141
8142         setfattr -x user.author1 $testfile ||
8143                 error "$testfile error deleting user.author1"
8144         echo "set lustre special xattr ..."
8145         $LFS setstripe -c1 $testfile
8146         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8147                 awk -F "=" '/trusted.lov/ { print $2 }' )
8148         setfattr -n "trusted.lov" -v $lovea $testfile ||
8149                 error "$testfile doesn't ignore setting trusted.lov again"
8150         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8151                 error "$testfile allow setting invalid trusted.lov"
8152         rm -f $testfile
8153 }
8154 run_test 102a "user xattr test =================================="
8155
8156 test_102b() {
8157         [ -z "$(which setfattr 2>/dev/null)" ] &&
8158                 skip_env "could not find setfattr"
8159         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8160
8161         # b10930: get/set/list trusted.lov xattr
8162         echo "get/set/list trusted.lov xattr ..."
8163         local testfile=$DIR/$tfile
8164         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8165                 error "setstripe failed"
8166         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8167                 error "getstripe failed"
8168         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8169                 error "can't get trusted.lov from $testfile"
8170
8171         local testfile2=${testfile}2
8172         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8173                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8174
8175         $MCREATE $testfile2
8176         setfattr -n trusted.lov -v $value $testfile2
8177         local stripe_size=$($LFS getstripe -S $testfile2)
8178         local stripe_count=$($LFS getstripe -c $testfile2)
8179         [[ $stripe_size -eq 65536 ]] ||
8180                 error "stripe size $stripe_size != 65536"
8181         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8182                 error "stripe count $stripe_count != $STRIPECOUNT"
8183         rm -f $DIR/$tfile
8184 }
8185 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8186
8187 test_102c() {
8188         [ -z "$(which setfattr 2>/dev/null)" ] &&
8189                 skip_env "could not find setfattr"
8190         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8191
8192         # b10930: get/set/list lustre.lov xattr
8193         echo "get/set/list lustre.lov xattr ..."
8194         test_mkdir $DIR/$tdir
8195         chown $RUNAS_ID $DIR/$tdir
8196         local testfile=$DIR/$tdir/$tfile
8197         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8198                 error "setstripe failed"
8199         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8200                 error "getstripe failed"
8201         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8202         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8203
8204         local testfile2=${testfile}2
8205         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8206                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8207
8208         $RUNAS $MCREATE $testfile2
8209         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8210         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8211         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8212         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8213         [ $stripe_count -eq $STRIPECOUNT ] ||
8214                 error "stripe count $stripe_count != $STRIPECOUNT"
8215 }
8216 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8217
8218 compare_stripe_info1() {
8219         local stripe_index_all_zero=true
8220
8221         for num in 1 2 3 4; do
8222                 for count in $(seq 1 $STRIPE_COUNT); do
8223                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8224                                 local size=$((STRIPE_SIZE * num))
8225                                 local file=file"$num-$offset-$count"
8226                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8227                                 [[ $stripe_size -ne $size ]] &&
8228                                     error "$file: size $stripe_size != $size"
8229                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8230                                 # allow fewer stripes to be created, ORI-601
8231                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8232                                     error "$file: count $stripe_count != $count"
8233                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8234                                 [[ $stripe_index -ne 0 ]] &&
8235                                         stripe_index_all_zero=false
8236                         done
8237                 done
8238         done
8239         $stripe_index_all_zero &&
8240                 error "all files are being extracted starting from OST index 0"
8241         return 0
8242 }
8243
8244 have_xattrs_include() {
8245         tar --help | grep -q xattrs-include &&
8246                 echo --xattrs-include="lustre.*"
8247 }
8248
8249 test_102d() {
8250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8251         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8252
8253         XINC=$(have_xattrs_include)
8254         setup_test102
8255         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8256         cd $DIR/$tdir/$tdir
8257         compare_stripe_info1
8258 }
8259 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8260
8261 test_102f() {
8262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8263         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8264
8265         XINC=$(have_xattrs_include)
8266         setup_test102
8267         test_mkdir $DIR/$tdir.restore
8268         cd $DIR
8269         tar cf - --xattrs $tdir | tar xf - \
8270                 -C $DIR/$tdir.restore --xattrs $XINC
8271         cd $DIR/$tdir.restore/$tdir
8272         compare_stripe_info1
8273 }
8274 run_test 102f "tar copy files, not keep osts"
8275
8276 grow_xattr() {
8277         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8278                 skip "must have user_xattr"
8279         [ -z "$(which setfattr 2>/dev/null)" ] &&
8280                 skip_env "could not find setfattr"
8281         [ -z "$(which getfattr 2>/dev/null)" ] &&
8282                 skip_env "could not find getfattr"
8283
8284         local xsize=${1:-1024}  # in bytes
8285         local file=$DIR/$tfile
8286         local value="$(generate_string $xsize)"
8287         local xbig=trusted.big
8288
8289         touch $file
8290         log "save $xbig on $file"
8291         setfattr -n $xbig -v $value $file ||
8292                 error "saving $xbig on $file failed"
8293
8294         local orig=$(get_xattr_value $xbig $file)
8295         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8296
8297         local xsml=trusted.sml
8298         log "save $xsml on $file"
8299         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8300
8301         local new=$(get_xattr_value $xbig $file)
8302         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8303
8304         log "grow $xsml on $file"
8305         setfattr -n $xsml -v "$value" $file ||
8306                 error "growing $xsml on $file failed"
8307
8308         new=$(get_xattr_value $xbig $file)
8309         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8310         log "$xbig still valid after growing $xsml"
8311
8312         rm -f $file
8313 }
8314
8315 test_102h() { # bug 15777
8316         grow_xattr 1024
8317 }
8318 run_test 102h "grow xattr from inside inode to external block"
8319
8320 test_102ha() {
8321         large_xattr_enabled || skip_env "ea_inode feature disabled"
8322
8323         grow_xattr $(max_xattr_size)
8324 }
8325 run_test 102ha "grow xattr from inside inode to external inode"
8326
8327 test_102i() { # bug 17038
8328         [ -z "$(which getfattr 2>/dev/null)" ] &&
8329                 skip "could not find getfattr"
8330
8331         touch $DIR/$tfile
8332         ln -s $DIR/$tfile $DIR/${tfile}link
8333         getfattr -n trusted.lov $DIR/$tfile ||
8334                 error "lgetxattr on $DIR/$tfile failed"
8335         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8336                 grep -i "no such attr" ||
8337                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8338         rm -f $DIR/$tfile $DIR/${tfile}link
8339 }
8340 run_test 102i "lgetxattr test on symbolic link ============"
8341
8342 test_102j() {
8343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8344         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8345
8346         XINC=$(have_xattrs_include)
8347         setup_test102 "$RUNAS"
8348         chown $RUNAS_ID $DIR/$tdir
8349         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8350         cd $DIR/$tdir/$tdir
8351         compare_stripe_info1 "$RUNAS"
8352 }
8353 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8354
8355 test_102k() {
8356         [ -z "$(which setfattr 2>/dev/null)" ] &&
8357                 skip "could not find setfattr"
8358
8359         touch $DIR/$tfile
8360         # b22187 just check that does not crash for regular file.
8361         setfattr -n trusted.lov $DIR/$tfile
8362         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8363         local test_kdir=$DIR/$tdir
8364         test_mkdir $test_kdir
8365         local default_size=$($LFS getstripe -S $test_kdir)
8366         local default_count=$($LFS getstripe -c $test_kdir)
8367         local default_offset=$($LFS getstripe -i $test_kdir)
8368         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8369                 error 'dir setstripe failed'
8370         setfattr -n trusted.lov $test_kdir
8371         local stripe_size=$($LFS getstripe -S $test_kdir)
8372         local stripe_count=$($LFS getstripe -c $test_kdir)
8373         local stripe_offset=$($LFS getstripe -i $test_kdir)
8374         [ $stripe_size -eq $default_size ] ||
8375                 error "stripe size $stripe_size != $default_size"
8376         [ $stripe_count -eq $default_count ] ||
8377                 error "stripe count $stripe_count != $default_count"
8378         [ $stripe_offset -eq $default_offset ] ||
8379                 error "stripe offset $stripe_offset != $default_offset"
8380         rm -rf $DIR/$tfile $test_kdir
8381 }
8382 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8383
8384 test_102l() {
8385         [ -z "$(which getfattr 2>/dev/null)" ] &&
8386                 skip "could not find getfattr"
8387
8388         # LU-532 trusted. xattr is invisible to non-root
8389         local testfile=$DIR/$tfile
8390
8391         touch $testfile
8392
8393         echo "listxattr as user..."
8394         chown $RUNAS_ID $testfile
8395         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8396             grep -q "trusted" &&
8397                 error "$testfile trusted xattrs are user visible"
8398
8399         return 0;
8400 }
8401 run_test 102l "listxattr size test =================================="
8402
8403 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8404         local path=$DIR/$tfile
8405         touch $path
8406
8407         listxattr_size_check $path || error "listattr_size_check $path failed"
8408 }
8409 run_test 102m "Ensure listxattr fails on small bufffer ========"
8410
8411 cleanup_test102
8412
8413 getxattr() { # getxattr path name
8414         # Return the base64 encoding of the value of xattr name on path.
8415         local path=$1
8416         local name=$2
8417
8418         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8419         # file: $path
8420         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8421         #
8422         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8423
8424         getfattr --absolute-names --encoding=base64 --name=$name $path |
8425                 awk -F= -v name=$name '$1 == name {
8426                         print substr($0, index($0, "=") + 1);
8427         }'
8428 }
8429
8430 test_102n() { # LU-4101 mdt: protect internal xattrs
8431         [ -z "$(which setfattr 2>/dev/null)" ] &&
8432                 skip "could not find setfattr"
8433         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
8434         then
8435                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
8436         fi
8437
8438         local file0=$DIR/$tfile.0
8439         local file1=$DIR/$tfile.1
8440         local xattr0=$TMP/$tfile.0
8441         local xattr1=$TMP/$tfile.1
8442         local namelist="lov lma lmv link fid version som hsm"
8443         local name
8444         local value
8445
8446         rm -rf $file0 $file1 $xattr0 $xattr1
8447         touch $file0 $file1
8448
8449         # Get 'before' xattrs of $file1.
8450         getfattr --absolute-names --dump --match=- $file1 > $xattr0
8451
8452         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
8453                 namelist+=" lfsck_namespace"
8454         for name in $namelist; do
8455                 # Try to copy xattr from $file0 to $file1.
8456                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8457
8458                 setfattr --name=trusted.$name --value="$value" $file1 ||
8459                         error "setxattr 'trusted.$name' failed"
8460
8461                 # Try to set a garbage xattr.
8462                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8463
8464                 if [[ x$name == "xlov" ]]; then
8465                         setfattr --name=trusted.lov --value="$value" $file1 &&
8466                         error "setxattr invalid 'trusted.lov' success"
8467                 else
8468                         setfattr --name=trusted.$name --value="$value" $file1 ||
8469                                 error "setxattr invalid 'trusted.$name' failed"
8470                 fi
8471
8472                 # Try to remove the xattr from $file1. We don't care if this
8473                 # appears to succeed or fail, we just don't want there to be
8474                 # any changes or crashes.
8475                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8476         done
8477
8478         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
8479         then
8480                 name="lfsck_ns"
8481                 # Try to copy xattr from $file0 to $file1.
8482                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8483
8484                 setfattr --name=trusted.$name --value="$value" $file1 ||
8485                         error "setxattr 'trusted.$name' failed"
8486
8487                 # Try to set a garbage xattr.
8488                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8489
8490                 setfattr --name=trusted.$name --value="$value" $file1 ||
8491                         error "setxattr 'trusted.$name' failed"
8492
8493                 # Try to remove the xattr from $file1. We don't care if this
8494                 # appears to succeed or fail, we just don't want there to be
8495                 # any changes or crashes.
8496                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8497         fi
8498
8499         # Get 'after' xattrs of file1.
8500         getfattr --absolute-names --dump --match=- $file1 > $xattr1
8501
8502         if ! diff $xattr0 $xattr1; then
8503                 error "before and after xattrs of '$file1' differ"
8504         fi
8505
8506         rm -rf $file0 $file1 $xattr0 $xattr1
8507
8508         return 0
8509 }
8510 run_test 102n "silently ignore setxattr on internal trusted xattrs"
8511
8512 test_102p() { # LU-4703 setxattr did not check ownership
8513         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
8514                 skip "MDS needs to be at least 2.5.56"
8515
8516         local testfile=$DIR/$tfile
8517
8518         touch $testfile
8519
8520         echo "setfacl as user..."
8521         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
8522         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
8523
8524         echo "setfattr as user..."
8525         setfacl -m "u:$RUNAS_ID:---" $testfile
8526         $RUNAS setfattr -x system.posix_acl_access $testfile
8527         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
8528 }
8529 run_test 102p "check setxattr(2) correctly fails without permission"
8530
8531 test_102q() {
8532         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
8533                 skip "MDS needs to be at least 2.6.92"
8534
8535         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
8536 }
8537 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
8538
8539 test_102r() {
8540         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
8541                 skip "MDS needs to be at least 2.6.93"
8542
8543         touch $DIR/$tfile || error "touch"
8544         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
8545         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
8546         rm $DIR/$tfile || error "rm"
8547
8548         #normal directory
8549         mkdir -p $DIR/$tdir || error "mkdir"
8550         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8551         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8552         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8553                 error "$testfile error deleting user.author1"
8554         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8555                 grep "user.$(basename $tdir)" &&
8556                 error "$tdir did not delete user.$(basename $tdir)"
8557         rmdir $DIR/$tdir || error "rmdir"
8558
8559         #striped directory
8560         test_mkdir $DIR/$tdir
8561         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8562         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8563         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8564                 error "$testfile error deleting user.author1"
8565         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8566                 grep "user.$(basename $tdir)" &&
8567                 error "$tdir did not delete user.$(basename $tdir)"
8568         rmdir $DIR/$tdir || error "rm striped dir"
8569 }
8570 run_test 102r "set EAs with empty values"
8571
8572 test_102s() {
8573         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8574                 skip "MDS needs to be at least 2.11.52"
8575
8576         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8577
8578         save_lustre_params client "llite.*.xattr_cache" > $save
8579
8580         for cache in 0 1; do
8581                 lctl set_param llite.*.xattr_cache=$cache
8582
8583                 rm -f $DIR/$tfile
8584                 touch $DIR/$tfile || error "touch"
8585                 for prefix in lustre security system trusted user; do
8586                         # Note getxattr() may fail with 'Operation not
8587                         # supported' or 'No such attribute' depending
8588                         # on prefix and cache.
8589                         getfattr -n $prefix.n102s $DIR/$tfile &&
8590                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
8591                 done
8592         done
8593
8594         restore_lustre_params < $save
8595 }
8596 run_test 102s "getting nonexistent xattrs should fail"
8597
8598 test_102t() {
8599         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8600                 skip "MDS needs to be at least 2.11.52"
8601
8602         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8603
8604         save_lustre_params client "llite.*.xattr_cache" > $save
8605
8606         for cache in 0 1; do
8607                 lctl set_param llite.*.xattr_cache=$cache
8608
8609                 for buf_size in 0 256; do
8610                         rm -f $DIR/$tfile
8611                         touch $DIR/$tfile || error "touch"
8612                         setfattr -n user.multiop $DIR/$tfile
8613                         $MULTIOP $DIR/$tfile oa$buf_size ||
8614                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
8615                 done
8616         done
8617
8618         restore_lustre_params < $save
8619 }
8620 run_test 102t "zero length xattr values handled correctly"
8621
8622 run_acl_subtest()
8623 {
8624     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
8625     return $?
8626 }
8627
8628 test_103a() {
8629         [ "$UID" != 0 ] && skip "must run as root"
8630         $GSS && skip_env "could not run under gss"
8631         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
8632                 skip_env "must have acl enabled"
8633         [ -z "$(which setfacl 2>/dev/null)" ] &&
8634                 skip_env "could not find setfacl"
8635         remote_mds_nodsh && skip "remote MDS with nodsh"
8636
8637         gpasswd -a daemon bin                           # LU-5641
8638         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
8639
8640         declare -a identity_old
8641
8642         for num in $(seq $MDSCOUNT); do
8643                 switch_identity $num true || identity_old[$num]=$?
8644         done
8645
8646         SAVE_UMASK=$(umask)
8647         umask 0022
8648         mkdir -p $DIR/$tdir
8649         cd $DIR/$tdir
8650
8651         echo "performing cp ..."
8652         run_acl_subtest cp || error "run_acl_subtest cp failed"
8653         echo "performing getfacl-noacl..."
8654         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
8655         echo "performing misc..."
8656         run_acl_subtest misc || error  "misc test failed"
8657         echo "performing permissions..."
8658         run_acl_subtest permissions || error "permissions failed"
8659         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
8660         if [ $MDS1_VERSION -gt $(version_code 2.8.55) -o \
8661              \( $MDS1_VERSION -lt $(version_code 2.6) -a \
8662              $MDS1_VERSION -ge $(version_code 2.5.29) \) ]
8663         then
8664                 echo "performing permissions xattr..."
8665                 run_acl_subtest permissions_xattr ||
8666                         error "permissions_xattr failed"
8667         fi
8668         echo "performing setfacl..."
8669         run_acl_subtest setfacl || error  "setfacl test failed"
8670
8671         # inheritance test got from HP
8672         echo "performing inheritance..."
8673         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
8674         chmod +x make-tree || error "chmod +x failed"
8675         run_acl_subtest inheritance || error "inheritance test failed"
8676         rm -f make-tree
8677
8678         echo "LU-974 ignore umask when acl is enabled..."
8679         run_acl_subtest 974 || error "LU-974 umask test failed"
8680         if [ $MDSCOUNT -ge 2 ]; then
8681                 run_acl_subtest 974_remote ||
8682                         error "LU-974 umask test failed under remote dir"
8683         fi
8684
8685         echo "LU-2561 newly created file is same size as directory..."
8686         if [ "$mds1_FSTYPE" != "zfs" ]; then
8687                 run_acl_subtest 2561 || error "LU-2561 test failed"
8688         else
8689                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
8690         fi
8691
8692         run_acl_subtest 4924 || error "LU-4924 test failed"
8693
8694         cd $SAVE_PWD
8695         umask $SAVE_UMASK
8696
8697         for num in $(seq $MDSCOUNT); do
8698                 if [ "${identity_old[$num]}" = 1 ]; then
8699                         switch_identity $num false || identity_old[$num]=$?
8700                 fi
8701         done
8702 }
8703 run_test 103a "acl test"
8704
8705 test_103b() {
8706         declare -a pids
8707         local U
8708
8709         for U in {0..511}; do
8710                 {
8711                 local O=$(printf "%04o" $U)
8712
8713                 umask $(printf "%04o" $((511 ^ $O)))
8714                 $LFS setstripe -c 1 $DIR/$tfile.s$O
8715                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
8716
8717                 (( $S == ($O & 0666) )) ||
8718                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
8719
8720                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
8721                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
8722                 (( $S == ($O & 0666) )) ||
8723                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
8724
8725                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
8726                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
8727                 (( $S == ($O & 0666) )) ||
8728                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
8729                 rm -f $DIR/$tfile.[smp]$0
8730                 } &
8731                 local pid=$!
8732
8733                 # limit the concurrently running threads to 64. LU-11878
8734                 local idx=$((U % 64))
8735                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
8736                 pids[idx]=$pid
8737         done
8738         wait
8739 }
8740 run_test 103b "umask lfs setstripe"
8741
8742 test_103c() {
8743         mkdir -p $DIR/$tdir
8744         cp -rp $DIR/$tdir $DIR/$tdir.bak
8745
8746         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
8747                 error "$DIR/$tdir shouldn't contain default ACL"
8748         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
8749                 error "$DIR/$tdir.bak shouldn't contain default ACL"
8750         true
8751 }
8752 run_test 103c "'cp -rp' won't set empty acl"
8753
8754 test_104a() {
8755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8756
8757         touch $DIR/$tfile
8758         lfs df || error "lfs df failed"
8759         lfs df -ih || error "lfs df -ih failed"
8760         lfs df -h $DIR || error "lfs df -h $DIR failed"
8761         lfs df -i $DIR || error "lfs df -i $DIR failed"
8762         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
8763         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
8764
8765         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
8766         lctl --device %$OSC deactivate
8767         lfs df || error "lfs df with deactivated OSC failed"
8768         lctl --device %$OSC activate
8769         # wait the osc back to normal
8770         wait_osc_import_ready client ost
8771
8772         lfs df || error "lfs df with reactivated OSC failed"
8773         rm -f $DIR/$tfile
8774 }
8775 run_test 104a "lfs df [-ih] [path] test ========================="
8776
8777 test_104b() {
8778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8779         [ $RUNAS_ID -eq $UID ] &&
8780                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8781
8782         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
8783                         grep "Permission denied" | wc -l)))
8784         if [ $denied_cnt -ne 0 ]; then
8785                 error "lfs check servers test failed"
8786         fi
8787 }
8788 run_test 104b "$RUNAS lfs check servers test ===================="
8789
8790 test_105a() {
8791         # doesn't work on 2.4 kernels
8792         touch $DIR/$tfile
8793         if $(flock_is_enabled); then
8794                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
8795         else
8796                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
8797         fi
8798         rm -f $DIR/$tfile
8799 }
8800 run_test 105a "flock when mounted without -o flock test ========"
8801
8802 test_105b() {
8803         touch $DIR/$tfile
8804         if $(flock_is_enabled); then
8805                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
8806         else
8807                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
8808         fi
8809         rm -f $DIR/$tfile
8810 }
8811 run_test 105b "fcntl when mounted without -o flock test ========"
8812
8813 test_105c() {
8814         touch $DIR/$tfile
8815         if $(flock_is_enabled); then
8816                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
8817         else
8818                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
8819         fi
8820         rm -f $DIR/$tfile
8821 }
8822 run_test 105c "lockf when mounted without -o flock test"
8823
8824 test_105d() { # bug 15924
8825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8826
8827         test_mkdir $DIR/$tdir
8828         flock_is_enabled || skip_env "mount w/o flock enabled"
8829         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
8830         $LCTL set_param fail_loc=0x80000315
8831         flocks_test 2 $DIR/$tdir
8832 }
8833 run_test 105d "flock race (should not freeze) ========"
8834
8835 test_105e() { # bug 22660 && 22040
8836         flock_is_enabled || skip_env "mount w/o flock enabled"
8837
8838         touch $DIR/$tfile
8839         flocks_test 3 $DIR/$tfile
8840 }
8841 run_test 105e "Two conflicting flocks from same process"
8842
8843 test_106() { #bug 10921
8844         test_mkdir $DIR/$tdir
8845         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
8846         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
8847 }
8848 run_test 106 "attempt exec of dir followed by chown of that dir"
8849
8850 test_107() {
8851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8852
8853         CDIR=`pwd`
8854         local file=core
8855
8856         cd $DIR
8857         rm -f $file
8858
8859         local save_pattern=$(sysctl -n kernel.core_pattern)
8860         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
8861         sysctl -w kernel.core_pattern=$file
8862         sysctl -w kernel.core_uses_pid=0
8863
8864         ulimit -c unlimited
8865         sleep 60 &
8866         SLEEPPID=$!
8867
8868         sleep 1
8869
8870         kill -s 11 $SLEEPPID
8871         wait $SLEEPPID
8872         if [ -e $file ]; then
8873                 size=`stat -c%s $file`
8874                 [ $size -eq 0 ] && error "Fail to create core file $file"
8875         else
8876                 error "Fail to create core file $file"
8877         fi
8878         rm -f $file
8879         sysctl -w kernel.core_pattern=$save_pattern
8880         sysctl -w kernel.core_uses_pid=$save_uses_pid
8881         cd $CDIR
8882 }
8883 run_test 107 "Coredump on SIG"
8884
8885 test_110() {
8886         test_mkdir $DIR/$tdir
8887         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
8888         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
8889                 error "mkdir with 256 char should fail, but did not"
8890         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
8891                 error "create with 255 char failed"
8892         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
8893                 error "create with 256 char should fail, but did not"
8894
8895         ls -l $DIR/$tdir
8896         rm -rf $DIR/$tdir
8897 }
8898 run_test 110 "filename length checking"
8899
8900 #
8901 # Purpose: To verify dynamic thread (OSS) creation.
8902 #
8903 test_115() {
8904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8905         remote_ost_nodsh && skip "remote OST with nodsh"
8906
8907         # Lustre does not stop service threads once they are started.
8908         # Reset number of running threads to default.
8909         stopall
8910         setupall
8911
8912         local OSTIO_pre
8913         local save_params="$TMP/sanity-$TESTNAME.parameters"
8914
8915         # Get ll_ost_io count before I/O
8916         OSTIO_pre=$(do_facet ost1 \
8917                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
8918         # Exit if lustre is not running (ll_ost_io not running).
8919         [ -z "$OSTIO_pre" ] && error "no OSS threads"
8920
8921         echo "Starting with $OSTIO_pre threads"
8922         local thread_max=$((OSTIO_pre * 2))
8923         local rpc_in_flight=$((thread_max * 2))
8924         # Number of I/O Process proposed to be started.
8925         local nfiles
8926         local facets=$(get_facets OST)
8927
8928         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
8929         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
8930
8931         # Set in_flight to $rpc_in_flight
8932         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
8933                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
8934         nfiles=${rpc_in_flight}
8935         # Set ost thread_max to $thread_max
8936         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
8937
8938         # 5 Minutes should be sufficient for max number of OSS
8939         # threads(thread_max) to be created.
8940         local timeout=300
8941
8942         # Start I/O.
8943         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
8944         test_mkdir $DIR/$tdir
8945         for i in $(seq $nfiles); do
8946                 local file=$DIR/$tdir/${tfile}-$i
8947                 $LFS setstripe -c -1 -i 0 $file
8948                 ($WTL $file $timeout)&
8949         done
8950
8951         # I/O Started - Wait for thread_started to reach thread_max or report
8952         # error if thread_started is more than thread_max.
8953         echo "Waiting for thread_started to reach thread_max"
8954         local thread_started=0
8955         local end_time=$((SECONDS + timeout))
8956
8957         while [ $SECONDS -le $end_time ] ; do
8958                 echo -n "."
8959                 # Get ost i/o thread_started count.
8960                 thread_started=$(do_facet ost1 \
8961                         "$LCTL get_param \
8962                         ost.OSS.ost_io.threads_started | cut -d= -f2")
8963                 # Break out if thread_started is equal/greater than thread_max
8964                 if [[ $thread_started -ge $thread_max ]]; then
8965                         echo ll_ost_io thread_started $thread_started, \
8966                                 equal/greater than thread_max $thread_max
8967                         break
8968                 fi
8969                 sleep 1
8970         done
8971
8972         # Cleanup - We have the numbers, Kill i/o jobs if running.
8973         jobcount=($(jobs -p))
8974         for i in $(seq 0 $((${#jobcount[@]}-1)))
8975         do
8976                 kill -9 ${jobcount[$i]}
8977                 if [ $? -ne 0 ] ; then
8978                         echo Warning: \
8979                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
8980                 fi
8981         done
8982
8983         # Cleanup files left by WTL binary.
8984         for i in $(seq $nfiles); do
8985                 local file=$DIR/$tdir/${tfile}-$i
8986                 rm -rf $file
8987                 if [ $? -ne 0 ] ; then
8988                         echo "Warning: Failed to delete file $file"
8989                 fi
8990         done
8991
8992         restore_lustre_params <$save_params
8993         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
8994
8995         # Error out if no new thread has started or Thread started is greater
8996         # than thread max.
8997         if [[ $thread_started -le $OSTIO_pre ||
8998                         $thread_started -gt $thread_max ]]; then
8999                 error "ll_ost_io: thread_started $thread_started" \
9000                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9001                       "No new thread started or thread started greater " \
9002                       "than thread_max."
9003         fi
9004 }
9005 run_test 115 "verify dynamic thread creation===================="
9006
9007 free_min_max () {
9008         wait_delete_completed
9009         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9010         echo "OST kbytes available: ${AVAIL[@]}"
9011         MAXV=${AVAIL[0]}
9012         MAXI=0
9013         MINV=${AVAIL[0]}
9014         MINI=0
9015         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9016                 #echo OST $i: ${AVAIL[i]}kb
9017                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9018                         MAXV=${AVAIL[i]}
9019                         MAXI=$i
9020                 fi
9021                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9022                         MINV=${AVAIL[i]}
9023                         MINI=$i
9024                 fi
9025         done
9026         echo "Min free space: OST $MINI: $MINV"
9027         echo "Max free space: OST $MAXI: $MAXV"
9028 }
9029
9030 test_116a() { # was previously test_116()
9031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9032         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9033         remote_mds_nodsh && skip "remote MDS with nodsh"
9034
9035         echo -n "Free space priority "
9036         do_facet $SINGLEMDS lctl get_param -n lo*.*-mdtlov.qos_prio_free |
9037                 head -n1
9038         declare -a AVAIL
9039         free_min_max
9040
9041         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9042         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9043         trap simple_cleanup_common EXIT
9044
9045         # Check if we need to generate uneven OSTs
9046         test_mkdir -p $DIR/$tdir/OST${MINI}
9047         local FILL=$((MINV / 4))
9048         local DIFF=$((MAXV - MINV))
9049         local DIFF2=$((DIFF * 100 / MINV))
9050
9051         local threshold=$(do_facet $SINGLEMDS \
9052                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9053         threshold=${threshold%%%}
9054         echo -n "Check for uneven OSTs: "
9055         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9056
9057         if [[ $DIFF2 -gt $threshold ]]; then
9058                 echo "ok"
9059                 echo "Don't need to fill OST$MINI"
9060         else
9061                 # generate uneven OSTs. Write 2% over the QOS threshold value
9062                 echo "no"
9063                 DIFF=$((threshold - DIFF2 + 2))
9064                 DIFF2=$((MINV * DIFF / 100))
9065                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9066                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9067                         error "setstripe failed"
9068                 DIFF=$((DIFF2 / 2048))
9069                 i=0
9070                 while [ $i -lt $DIFF ]; do
9071                         i=$((i + 1))
9072                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9073                                 bs=2M count=1 2>/dev/null
9074                         echo -n .
9075                 done
9076                 echo .
9077                 sync
9078                 sleep_maxage
9079                 free_min_max
9080         fi
9081
9082         DIFF=$((MAXV - MINV))
9083         DIFF2=$((DIFF * 100 / MINV))
9084         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9085         if [ $DIFF2 -gt $threshold ]; then
9086                 echo "ok"
9087         else
9088                 echo "failed - QOS mode won't be used"
9089                 simple_cleanup_common
9090                 skip "QOS imbalance criteria not met"
9091         fi
9092
9093         MINI1=$MINI
9094         MINV1=$MINV
9095         MAXI1=$MAXI
9096         MAXV1=$MAXV
9097
9098         # now fill using QOS
9099         $LFS setstripe -c 1 $DIR/$tdir
9100         FILL=$((FILL / 200))
9101         if [ $FILL -gt 600 ]; then
9102                 FILL=600
9103         fi
9104         echo "writing $FILL files to QOS-assigned OSTs"
9105         i=0
9106         while [ $i -lt $FILL ]; do
9107                 i=$((i + 1))
9108                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9109                         count=1 2>/dev/null
9110                 echo -n .
9111         done
9112         echo "wrote $i 200k files"
9113         sync
9114         sleep_maxage
9115
9116         echo "Note: free space may not be updated, so measurements might be off"
9117         free_min_max
9118         DIFF2=$((MAXV - MINV))
9119         echo "free space delta: orig $DIFF final $DIFF2"
9120         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9121         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9122         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9123         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9124         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9125         if [[ $DIFF -gt 0 ]]; then
9126                 FILL=$((DIFF2 * 100 / DIFF - 100))
9127                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9128         fi
9129
9130         # Figure out which files were written where
9131         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9132                awk '/'$MINI1': / {print $2; exit}')
9133         echo $UUID
9134         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9135         echo "$MINC files created on smaller OST $MINI1"
9136         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9137                awk '/'$MAXI1': / {print $2; exit}')
9138         echo $UUID
9139         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9140         echo "$MAXC files created on larger OST $MAXI1"
9141         if [[ $MINC -gt 0 ]]; then
9142                 FILL=$((MAXC * 100 / MINC - 100))
9143                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9144         fi
9145         [[ $MAXC -gt $MINC ]] ||
9146                 error_ignore LU-9 "stripe QOS didn't balance free space"
9147         simple_cleanup_common
9148 }
9149 run_test 116a "stripe QOS: free space balance ==================="
9150
9151 test_116b() { # LU-2093
9152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9153         remote_mds_nodsh && skip "remote MDS with nodsh"
9154
9155 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9156         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9157                        lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9158         [ -z "$old_rr" ] && skip "no QOS"
9159         do_facet $SINGLEMDS lctl set_param \
9160                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9161         mkdir -p $DIR/$tdir
9162         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9163         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9164         do_facet $SINGLEMDS lctl set_param fail_loc=0
9165         rm -rf $DIR/$tdir
9166         do_facet $SINGLEMDS lctl set_param \
9167                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9168 }
9169 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9170
9171 test_117() # bug 10891
9172 {
9173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9174
9175         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9176         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9177         lctl set_param fail_loc=0x21e
9178         > $DIR/$tfile || error "truncate failed"
9179         lctl set_param fail_loc=0
9180         echo "Truncate succeeded."
9181         rm -f $DIR/$tfile
9182 }
9183 run_test 117 "verify osd extend =========="
9184
9185 NO_SLOW_RESENDCOUNT=4
9186 export OLD_RESENDCOUNT=""
9187 set_resend_count () {
9188         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9189         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9190         lctl set_param -n $PROC_RESENDCOUNT $1
9191         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9192 }
9193
9194 # for reduce test_118* time (b=14842)
9195 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9196
9197 # Reset async IO behavior after error case
9198 reset_async() {
9199         FILE=$DIR/reset_async
9200
9201         # Ensure all OSCs are cleared
9202         $LFS setstripe -c -1 $FILE
9203         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9204         sync
9205         rm $FILE
9206 }
9207
9208 test_118a() #bug 11710
9209 {
9210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9211
9212         reset_async
9213
9214         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9215         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9216         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9217
9218         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9219                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9220                 return 1;
9221         fi
9222         rm -f $DIR/$tfile
9223 }
9224 run_test 118a "verify O_SYNC works =========="
9225
9226 test_118b()
9227 {
9228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9229         remote_ost_nodsh && skip "remote OST with nodsh"
9230
9231         reset_async
9232
9233         #define OBD_FAIL_SRV_ENOENT 0x217
9234         set_nodes_failloc "$(osts_nodes)" 0x217
9235         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9236         RC=$?
9237         set_nodes_failloc "$(osts_nodes)" 0
9238         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9239         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9240                     grep -c writeback)
9241
9242         if [[ $RC -eq 0 ]]; then
9243                 error "Must return error due to dropped pages, rc=$RC"
9244                 return 1;
9245         fi
9246
9247         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9248                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9249                 return 1;
9250         fi
9251
9252         echo "Dirty pages not leaked on ENOENT"
9253
9254         # Due to the above error the OSC will issue all RPCs syncronously
9255         # until a subsequent RPC completes successfully without error.
9256         $MULTIOP $DIR/$tfile Ow4096yc
9257         rm -f $DIR/$tfile
9258
9259         return 0
9260 }
9261 run_test 118b "Reclaim dirty pages on fatal error =========="
9262
9263 test_118c()
9264 {
9265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9266
9267         # for 118c, restore the original resend count, LU-1940
9268         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9269                                 set_resend_count $OLD_RESENDCOUNT
9270         remote_ost_nodsh && skip "remote OST with nodsh"
9271
9272         reset_async
9273
9274         #define OBD_FAIL_OST_EROFS               0x216
9275         set_nodes_failloc "$(osts_nodes)" 0x216
9276
9277         # multiop should block due to fsync until pages are written
9278         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9279         MULTIPID=$!
9280         sleep 1
9281
9282         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9283                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9284         fi
9285
9286         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9287                     grep -c writeback)
9288         if [[ $WRITEBACK -eq 0 ]]; then
9289                 error "No page in writeback, writeback=$WRITEBACK"
9290         fi
9291
9292         set_nodes_failloc "$(osts_nodes)" 0
9293         wait $MULTIPID
9294         RC=$?
9295         if [[ $RC -ne 0 ]]; then
9296                 error "Multiop fsync failed, rc=$RC"
9297         fi
9298
9299         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9300         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9301                     grep -c writeback)
9302         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9303                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9304         fi
9305
9306         rm -f $DIR/$tfile
9307         echo "Dirty pages flushed via fsync on EROFS"
9308         return 0
9309 }
9310 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9311
9312 # continue to use small resend count to reduce test_118* time (b=14842)
9313 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9314
9315 test_118d()
9316 {
9317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9318         remote_ost_nodsh && skip "remote OST with nodsh"
9319
9320         reset_async
9321
9322         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9323         set_nodes_failloc "$(osts_nodes)" 0x214
9324         # multiop should block due to fsync until pages are written
9325         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9326         MULTIPID=$!
9327         sleep 1
9328
9329         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9330                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9331         fi
9332
9333         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9334                     grep -c writeback)
9335         if [[ $WRITEBACK -eq 0 ]]; then
9336                 error "No page in writeback, writeback=$WRITEBACK"
9337         fi
9338
9339         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9340         set_nodes_failloc "$(osts_nodes)" 0
9341
9342         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9343         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9344                     grep -c writeback)
9345         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9346                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9347         fi
9348
9349         rm -f $DIR/$tfile
9350         echo "Dirty pages gaurenteed flushed via fsync"
9351         return 0
9352 }
9353 run_test 118d "Fsync validation inject a delay of the bulk =========="
9354
9355 test_118f() {
9356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9357
9358         reset_async
9359
9360         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9361         lctl set_param fail_loc=0x8000040a
9362
9363         # Should simulate EINVAL error which is fatal
9364         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9365         RC=$?
9366         if [[ $RC -eq 0 ]]; then
9367                 error "Must return error due to dropped pages, rc=$RC"
9368         fi
9369
9370         lctl set_param fail_loc=0x0
9371
9372         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9373         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9374         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9375                     grep -c writeback)
9376         if [[ $LOCKED -ne 0 ]]; then
9377                 error "Locked pages remain in cache, locked=$LOCKED"
9378         fi
9379
9380         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9381                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9382         fi
9383
9384         rm -f $DIR/$tfile
9385         echo "No pages locked after fsync"
9386
9387         reset_async
9388         return 0
9389 }
9390 run_test 118f "Simulate unrecoverable OSC side error =========="
9391
9392 test_118g() {
9393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9394
9395         reset_async
9396
9397         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9398         lctl set_param fail_loc=0x406
9399
9400         # simulate local -ENOMEM
9401         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9402         RC=$?
9403
9404         lctl set_param fail_loc=0
9405         if [[ $RC -eq 0 ]]; then
9406                 error "Must return error due to dropped pages, rc=$RC"
9407         fi
9408
9409         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9410         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9411         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9412                         grep -c writeback)
9413         if [[ $LOCKED -ne 0 ]]; then
9414                 error "Locked pages remain in cache, locked=$LOCKED"
9415         fi
9416
9417         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9418                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9419         fi
9420
9421         rm -f $DIR/$tfile
9422         echo "No pages locked after fsync"
9423
9424         reset_async
9425         return 0
9426 }
9427 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9428
9429 test_118h() {
9430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9431         remote_ost_nodsh && skip "remote OST with nodsh"
9432
9433         reset_async
9434
9435         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9436         set_nodes_failloc "$(osts_nodes)" 0x20e
9437         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9438         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9439         RC=$?
9440
9441         set_nodes_failloc "$(osts_nodes)" 0
9442         if [[ $RC -eq 0 ]]; then
9443                 error "Must return error due to dropped pages, rc=$RC"
9444         fi
9445
9446         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9447         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9448         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9449                     grep -c writeback)
9450         if [[ $LOCKED -ne 0 ]]; then
9451                 error "Locked pages remain in cache, locked=$LOCKED"
9452         fi
9453
9454         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9455                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9456         fi
9457
9458         rm -f $DIR/$tfile
9459         echo "No pages locked after fsync"
9460
9461         return 0
9462 }
9463 run_test 118h "Verify timeout in handling recoverables errors  =========="
9464
9465 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9466
9467 test_118i() {
9468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9469         remote_ost_nodsh && skip "remote OST with nodsh"
9470
9471         reset_async
9472
9473         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9474         set_nodes_failloc "$(osts_nodes)" 0x20e
9475
9476         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9477         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9478         PID=$!
9479         sleep 5
9480         set_nodes_failloc "$(osts_nodes)" 0
9481
9482         wait $PID
9483         RC=$?
9484         if [[ $RC -ne 0 ]]; then
9485                 error "got error, but should be not, rc=$RC"
9486         fi
9487
9488         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9489         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9490         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9491         if [[ $LOCKED -ne 0 ]]; then
9492                 error "Locked pages remain in cache, locked=$LOCKED"
9493         fi
9494
9495         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9496                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9497         fi
9498
9499         rm -f $DIR/$tfile
9500         echo "No pages locked after fsync"
9501
9502         return 0
9503 }
9504 run_test 118i "Fix error before timeout in recoverable error  =========="
9505
9506 [ "$SLOW" = "no" ] && set_resend_count 4
9507
9508 test_118j() {
9509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9510         remote_ost_nodsh && skip "remote OST with nodsh"
9511
9512         reset_async
9513
9514         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
9515         set_nodes_failloc "$(osts_nodes)" 0x220
9516
9517         # return -EIO from OST
9518         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9519         RC=$?
9520         set_nodes_failloc "$(osts_nodes)" 0x0
9521         if [[ $RC -eq 0 ]]; then
9522                 error "Must return error due to dropped pages, rc=$RC"
9523         fi
9524
9525         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9526         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9527         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9528         if [[ $LOCKED -ne 0 ]]; then
9529                 error "Locked pages remain in cache, locked=$LOCKED"
9530         fi
9531
9532         # in recoverable error on OST we want resend and stay until it finished
9533         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9534                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9535         fi
9536
9537         rm -f $DIR/$tfile
9538         echo "No pages locked after fsync"
9539
9540         return 0
9541 }
9542 run_test 118j "Simulate unrecoverable OST side error =========="
9543
9544 test_118k()
9545 {
9546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9547         remote_ost_nodsh && skip "remote OSTs with nodsh"
9548
9549         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9550         set_nodes_failloc "$(osts_nodes)" 0x20e
9551         test_mkdir $DIR/$tdir
9552
9553         for ((i=0;i<10;i++)); do
9554                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
9555                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
9556                 SLEEPPID=$!
9557                 sleep 0.500s
9558                 kill $SLEEPPID
9559                 wait $SLEEPPID
9560         done
9561
9562         set_nodes_failloc "$(osts_nodes)" 0
9563         rm -rf $DIR/$tdir
9564 }
9565 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
9566
9567 test_118l() # LU-646
9568 {
9569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9570
9571         test_mkdir $DIR/$tdir
9572         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
9573         rm -rf $DIR/$tdir
9574 }
9575 run_test 118l "fsync dir"
9576
9577 test_118m() # LU-3066
9578 {
9579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9580
9581         test_mkdir $DIR/$tdir
9582         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
9583         rm -rf $DIR/$tdir
9584 }
9585 run_test 118m "fdatasync dir ========="
9586
9587 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9588
9589 test_118n()
9590 {
9591         local begin
9592         local end
9593
9594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9595         remote_ost_nodsh && skip "remote OSTs with nodsh"
9596
9597         # Sleep to avoid a cached response.
9598         #define OBD_STATFS_CACHE_SECONDS 1
9599         sleep 2
9600
9601         # Inject a 10 second delay in the OST_STATFS handler.
9602         #define OBD_FAIL_OST_STATFS_DELAY 0x242
9603         set_nodes_failloc "$(osts_nodes)" 0x242
9604
9605         begin=$SECONDS
9606         stat --file-system $MOUNT > /dev/null
9607         end=$SECONDS
9608
9609         set_nodes_failloc "$(osts_nodes)" 0
9610
9611         if ((end - begin > 20)); then
9612             error "statfs took $((end - begin)) seconds, expected 10"
9613         fi
9614 }
9615 run_test 118n "statfs() sends OST_STATFS requests in parallel"
9616
9617 test_119a() # bug 11737
9618 {
9619         BSIZE=$((512 * 1024))
9620         directio write $DIR/$tfile 0 1 $BSIZE
9621         # We ask to read two blocks, which is more than a file size.
9622         # directio will indicate an error when requested and actual
9623         # sizes aren't equeal (a normal situation in this case) and
9624         # print actual read amount.
9625         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
9626         if [ "$NOB" != "$BSIZE" ]; then
9627                 error "read $NOB bytes instead of $BSIZE"
9628         fi
9629         rm -f $DIR/$tfile
9630 }
9631 run_test 119a "Short directIO read must return actual read amount"
9632
9633 test_119b() # bug 11737
9634 {
9635         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9636
9637         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
9638         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
9639         sync
9640         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
9641                 error "direct read failed"
9642         rm -f $DIR/$tfile
9643 }
9644 run_test 119b "Sparse directIO read must return actual read amount"
9645
9646 test_119c() # bug 13099
9647 {
9648         BSIZE=1048576
9649         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
9650         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
9651         rm -f $DIR/$tfile
9652 }
9653 run_test 119c "Testing for direct read hitting hole"
9654
9655 test_119d() # bug 15950
9656 {
9657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9658
9659         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
9660         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
9661         BSIZE=1048576
9662         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
9663         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
9664         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
9665         lctl set_param fail_loc=0x40d
9666         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
9667         pid_dio=$!
9668         sleep 1
9669         cat $DIR/$tfile > /dev/null &
9670         lctl set_param fail_loc=0
9671         pid_reads=$!
9672         wait $pid_dio
9673         log "the DIO writes have completed, now wait for the reads (should not block very long)"
9674         sleep 2
9675         [ -n "`ps h -p $pid_reads -o comm`" ] && \
9676         error "the read rpcs have not completed in 2s"
9677         rm -f $DIR/$tfile
9678         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
9679 }
9680 run_test 119d "The DIO path should try to send a new rpc once one is completed"
9681
9682 test_120a() {
9683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9684         remote_mds_nodsh && skip "remote MDS with nodsh"
9685         test_mkdir $DIR/$tdir
9686         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9687                 skip_env "no early lock cancel on server"
9688
9689         lru_resize_disable mdc
9690         lru_resize_disable osc
9691         cancel_lru_locks mdc
9692         # asynchronous object destroy at MDT could cause bl ast to client
9693         cancel_lru_locks osc
9694
9695         stat $DIR/$tdir > /dev/null
9696         can1=$(do_facet $SINGLEMDS \
9697                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9698                awk '/ldlm_cancel/ {print $2}')
9699         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9700                awk '/ldlm_bl_callback/ {print $2}')
9701         test_mkdir -c1 $DIR/$tdir/d1
9702         can2=$(do_facet $SINGLEMDS \
9703                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9704                awk '/ldlm_cancel/ {print $2}')
9705         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9706                awk '/ldlm_bl_callback/ {print $2}')
9707         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9708         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9709         lru_resize_enable mdc
9710         lru_resize_enable osc
9711 }
9712 run_test 120a "Early Lock Cancel: mkdir test"
9713
9714 test_120b() {
9715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9716         remote_mds_nodsh && skip "remote MDS with nodsh"
9717         test_mkdir $DIR/$tdir
9718         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9719                 skip_env "no early lock cancel on server"
9720
9721         lru_resize_disable mdc
9722         lru_resize_disable osc
9723         cancel_lru_locks mdc
9724         stat $DIR/$tdir > /dev/null
9725         can1=$(do_facet $SINGLEMDS \
9726                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9727                awk '/ldlm_cancel/ {print $2}')
9728         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9729                awk '/ldlm_bl_callback/ {print $2}')
9730         touch $DIR/$tdir/f1
9731         can2=$(do_facet $SINGLEMDS \
9732                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9733                awk '/ldlm_cancel/ {print $2}')
9734         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9735                awk '/ldlm_bl_callback/ {print $2}')
9736         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9737         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9738         lru_resize_enable mdc
9739         lru_resize_enable osc
9740 }
9741 run_test 120b "Early Lock Cancel: create test"
9742
9743 test_120c() {
9744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9745         remote_mds_nodsh && skip "remote MDS with nodsh"
9746         test_mkdir -c1 $DIR/$tdir
9747         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9748                 skip "no early lock cancel on server"
9749
9750         lru_resize_disable mdc
9751         lru_resize_disable osc
9752         test_mkdir -c1 $DIR/$tdir/d1
9753         test_mkdir -c1 $DIR/$tdir/d2
9754         touch $DIR/$tdir/d1/f1
9755         cancel_lru_locks mdc
9756         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
9757         can1=$(do_facet $SINGLEMDS \
9758                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9759                awk '/ldlm_cancel/ {print $2}')
9760         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9761                awk '/ldlm_bl_callback/ {print $2}')
9762         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9763         can2=$(do_facet $SINGLEMDS \
9764                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9765                awk '/ldlm_cancel/ {print $2}')
9766         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9767                awk '/ldlm_bl_callback/ {print $2}')
9768         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9769         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9770         lru_resize_enable mdc
9771         lru_resize_enable osc
9772 }
9773 run_test 120c "Early Lock Cancel: link test"
9774
9775 test_120d() {
9776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9777         remote_mds_nodsh && skip "remote MDS with nodsh"
9778         test_mkdir -c1 $DIR/$tdir
9779         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9780                 skip_env "no early lock cancel on server"
9781
9782         lru_resize_disable mdc
9783         lru_resize_disable osc
9784         touch $DIR/$tdir
9785         cancel_lru_locks mdc
9786         stat $DIR/$tdir > /dev/null
9787         can1=$(do_facet $SINGLEMDS \
9788                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9789                awk '/ldlm_cancel/ {print $2}')
9790         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9791                awk '/ldlm_bl_callback/ {print $2}')
9792         chmod a+x $DIR/$tdir
9793         can2=$(do_facet $SINGLEMDS \
9794                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9795                awk '/ldlm_cancel/ {print $2}')
9796         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9797                awk '/ldlm_bl_callback/ {print $2}')
9798         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9799         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9800         lru_resize_enable mdc
9801         lru_resize_enable osc
9802 }
9803 run_test 120d "Early Lock Cancel: setattr test"
9804
9805 test_120e() {
9806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9807         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9808                 skip_env "no early lock cancel on server"
9809         remote_mds_nodsh && skip "remote MDS with nodsh"
9810
9811         local dlmtrace_set=false
9812
9813         test_mkdir -c1 $DIR/$tdir
9814         lru_resize_disable mdc
9815         lru_resize_disable osc
9816         ! $LCTL get_param debug | grep -q dlmtrace &&
9817                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
9818         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
9819         cancel_lru_locks mdc
9820         cancel_lru_locks osc
9821         dd if=$DIR/$tdir/f1 of=/dev/null
9822         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
9823         # XXX client can not do early lock cancel of OST lock
9824         # during unlink (LU-4206), so cancel osc lock now.
9825         sleep 2
9826         cancel_lru_locks osc
9827         can1=$(do_facet $SINGLEMDS \
9828                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9829                awk '/ldlm_cancel/ {print $2}')
9830         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9831                awk '/ldlm_bl_callback/ {print $2}')
9832         unlink $DIR/$tdir/f1
9833         sleep 5
9834         can2=$(do_facet $SINGLEMDS \
9835                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9836                awk '/ldlm_cancel/ {print $2}')
9837         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9838                awk '/ldlm_bl_callback/ {print $2}')
9839         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
9840                 $LCTL dk $TMP/cancel.debug.txt
9841         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
9842                 $LCTL dk $TMP/blocking.debug.txt
9843         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
9844         lru_resize_enable mdc
9845         lru_resize_enable osc
9846 }
9847 run_test 120e "Early Lock Cancel: unlink test"
9848
9849 test_120f() {
9850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9851         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9852                 skip_env "no early lock cancel on server"
9853         remote_mds_nodsh && skip "remote MDS with nodsh"
9854
9855         test_mkdir -c1 $DIR/$tdir
9856         lru_resize_disable mdc
9857         lru_resize_disable osc
9858         test_mkdir -c1 $DIR/$tdir/d1
9859         test_mkdir -c1 $DIR/$tdir/d2
9860         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
9861         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
9862         cancel_lru_locks mdc
9863         cancel_lru_locks osc
9864         dd if=$DIR/$tdir/d1/f1 of=/dev/null
9865         dd if=$DIR/$tdir/d2/f2 of=/dev/null
9866         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
9867         # XXX client can not do early lock cancel of OST lock
9868         # during rename (LU-4206), so cancel osc lock now.
9869         sleep 2
9870         cancel_lru_locks osc
9871         can1=$(do_facet $SINGLEMDS \
9872                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9873                awk '/ldlm_cancel/ {print $2}')
9874         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9875                awk '/ldlm_bl_callback/ {print $2}')
9876         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9877         sleep 5
9878         can2=$(do_facet $SINGLEMDS \
9879                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9880                awk '/ldlm_cancel/ {print $2}')
9881         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9882                awk '/ldlm_bl_callback/ {print $2}')
9883         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9884         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9885         lru_resize_enable mdc
9886         lru_resize_enable osc
9887 }
9888 run_test 120f "Early Lock Cancel: rename test"
9889
9890 test_120g() {
9891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9892         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9893                 skip_env "no early lock cancel on server"
9894         remote_mds_nodsh && skip "remote MDS with nodsh"
9895
9896         lru_resize_disable mdc
9897         lru_resize_disable osc
9898         count=10000
9899         echo create $count files
9900         test_mkdir $DIR/$tdir
9901         cancel_lru_locks mdc
9902         cancel_lru_locks osc
9903         t0=$(date +%s)
9904
9905         can0=$(do_facet $SINGLEMDS \
9906                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9907                awk '/ldlm_cancel/ {print $2}')
9908         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9909                awk '/ldlm_bl_callback/ {print $2}')
9910         createmany -o $DIR/$tdir/f $count
9911         sync
9912         can1=$(do_facet $SINGLEMDS \
9913                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9914                awk '/ldlm_cancel/ {print $2}')
9915         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9916                awk '/ldlm_bl_callback/ {print $2}')
9917         t1=$(date +%s)
9918         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
9919         echo rm $count files
9920         rm -r $DIR/$tdir
9921         sync
9922         can2=$(do_facet $SINGLEMDS \
9923                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9924                awk '/ldlm_cancel/ {print $2}')
9925         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9926                awk '/ldlm_bl_callback/ {print $2}')
9927         t2=$(date +%s)
9928         echo total: $count removes in $((t2-t1))
9929         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
9930         sleep 2
9931         # wait for commitment of removal
9932         lru_resize_enable mdc
9933         lru_resize_enable osc
9934 }
9935 run_test 120g "Early Lock Cancel: performance test"
9936
9937 test_121() { #bug #10589
9938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9939
9940         rm -rf $DIR/$tfile
9941         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
9942 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
9943         lctl set_param fail_loc=0x310
9944         cancel_lru_locks osc > /dev/null
9945         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
9946         lctl set_param fail_loc=0
9947         [[ $reads -eq $writes ]] ||
9948                 error "read $reads blocks, must be $writes blocks"
9949 }
9950 run_test 121 "read cancel race ========="
9951
9952 test_123a() { # was test 123, statahead(bug 11401)
9953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9954
9955         SLOWOK=0
9956         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
9957                 log "testing UP system. Performance may be lower than expected."
9958                 SLOWOK=1
9959         fi
9960
9961         rm -rf $DIR/$tdir
9962         test_mkdir $DIR/$tdir
9963         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
9964         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
9965         MULT=10
9966         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
9967                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
9968
9969                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
9970                 lctl set_param -n llite.*.statahead_max 0
9971                 lctl get_param llite.*.statahead_max
9972                 cancel_lru_locks mdc
9973                 cancel_lru_locks osc
9974                 stime=`date +%s`
9975                 time ls -l $DIR/$tdir | wc -l
9976                 etime=`date +%s`
9977                 delta=$((etime - stime))
9978                 log "ls $i files without statahead: $delta sec"
9979                 lctl set_param llite.*.statahead_max=$max
9980
9981                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
9982                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
9983                 cancel_lru_locks mdc
9984                 cancel_lru_locks osc
9985                 stime=`date +%s`
9986                 time ls -l $DIR/$tdir | wc -l
9987                 etime=`date +%s`
9988                 delta_sa=$((etime - stime))
9989                 log "ls $i files with statahead: $delta_sa sec"
9990                 lctl get_param -n llite.*.statahead_stats
9991                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
9992
9993                 [[ $swrong -lt $ewrong ]] &&
9994                         log "statahead was stopped, maybe too many locks held!"
9995                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
9996
9997                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
9998                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
9999                     lctl set_param -n llite.*.statahead_max 0
10000                     lctl get_param llite.*.statahead_max
10001                     cancel_lru_locks mdc
10002                     cancel_lru_locks osc
10003                     stime=`date +%s`
10004                     time ls -l $DIR/$tdir | wc -l
10005                     etime=`date +%s`
10006                     delta=$((etime - stime))
10007                     log "ls $i files again without statahead: $delta sec"
10008                     lctl set_param llite.*.statahead_max=$max
10009                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10010                         if [  $SLOWOK -eq 0 ]; then
10011                                 error "ls $i files is slower with statahead!"
10012                         else
10013                                 log "ls $i files is slower with statahead!"
10014                         fi
10015                         break
10016                     fi
10017                 fi
10018
10019                 [ $delta -gt 20 ] && break
10020                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10021                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10022         done
10023         log "ls done"
10024
10025         stime=`date +%s`
10026         rm -r $DIR/$tdir
10027         sync
10028         etime=`date +%s`
10029         delta=$((etime - stime))
10030         log "rm -r $DIR/$tdir/: $delta seconds"
10031         log "rm done"
10032         lctl get_param -n llite.*.statahead_stats
10033 }
10034 run_test 123a "verify statahead work"
10035
10036 test_123b () { # statahead(bug 15027)
10037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10038
10039         test_mkdir $DIR/$tdir
10040         createmany -o $DIR/$tdir/$tfile-%d 1000
10041
10042         cancel_lru_locks mdc
10043         cancel_lru_locks osc
10044
10045 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10046         lctl set_param fail_loc=0x80000803
10047         ls -lR $DIR/$tdir > /dev/null
10048         log "ls done"
10049         lctl set_param fail_loc=0x0
10050         lctl get_param -n llite.*.statahead_stats
10051         rm -r $DIR/$tdir
10052         sync
10053
10054 }
10055 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10056
10057 test_124a() {
10058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10059         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10060                 skip_env "no lru resize on server"
10061
10062         local NR=2000
10063
10064         test_mkdir $DIR/$tdir
10065
10066         log "create $NR files at $DIR/$tdir"
10067         createmany -o $DIR/$tdir/f $NR ||
10068                 error "failed to create $NR files in $DIR/$tdir"
10069
10070         cancel_lru_locks mdc
10071         ls -l $DIR/$tdir > /dev/null
10072
10073         local NSDIR=""
10074         local LRU_SIZE=0
10075         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10076                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10077                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10078                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10079                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10080                         log "NSDIR=$NSDIR"
10081                         log "NS=$(basename $NSDIR)"
10082                         break
10083                 fi
10084         done
10085
10086         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10087                 skip "Not enough cached locks created!"
10088         fi
10089         log "LRU=$LRU_SIZE"
10090
10091         local SLEEP=30
10092
10093         # We know that lru resize allows one client to hold $LIMIT locks
10094         # for 10h. After that locks begin to be killed by client.
10095         local MAX_HRS=10
10096         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10097         log "LIMIT=$LIMIT"
10098         if [ $LIMIT -lt $LRU_SIZE ]; then
10099                 skip "Limit is too small $LIMIT"
10100         fi
10101
10102         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10103         # killing locks. Some time was spent for creating locks. This means
10104         # that up to the moment of sleep finish we must have killed some of
10105         # them (10-100 locks). This depends on how fast ther were created.
10106         # Many of them were touched in almost the same moment and thus will
10107         # be killed in groups.
10108         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10109
10110         # Use $LRU_SIZE_B here to take into account real number of locks
10111         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10112         local LRU_SIZE_B=$LRU_SIZE
10113         log "LVF=$LVF"
10114         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10115         log "OLD_LVF=$OLD_LVF"
10116         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10117
10118         # Let's make sure that we really have some margin. Client checks
10119         # cached locks every 10 sec.
10120         SLEEP=$((SLEEP+20))
10121         log "Sleep ${SLEEP} sec"
10122         local SEC=0
10123         while ((SEC<$SLEEP)); do
10124                 echo -n "..."
10125                 sleep 5
10126                 SEC=$((SEC+5))
10127                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10128                 echo -n "$LRU_SIZE"
10129         done
10130         echo ""
10131         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10132         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10133
10134         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10135                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10136                 unlinkmany $DIR/$tdir/f $NR
10137                 return
10138         }
10139
10140         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10141         log "unlink $NR files at $DIR/$tdir"
10142         unlinkmany $DIR/$tdir/f $NR
10143 }
10144 run_test 124a "lru resize ======================================="
10145
10146 get_max_pool_limit()
10147 {
10148         local limit=$($LCTL get_param \
10149                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10150         local max=0
10151         for l in $limit; do
10152                 if [[ $l -gt $max ]]; then
10153                         max=$l
10154                 fi
10155         done
10156         echo $max
10157 }
10158
10159 test_124b() {
10160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10161         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10162                 skip_env "no lru resize on server"
10163
10164         LIMIT=$(get_max_pool_limit)
10165
10166         NR=$(($(default_lru_size)*20))
10167         if [[ $NR -gt $LIMIT ]]; then
10168                 log "Limit lock number by $LIMIT locks"
10169                 NR=$LIMIT
10170         fi
10171
10172         IFree=$(mdsrate_inodes_available)
10173         if [ $IFree -lt $NR ]; then
10174                 log "Limit lock number by $IFree inodes"
10175                 NR=$IFree
10176         fi
10177
10178         lru_resize_disable mdc
10179         test_mkdir -p $DIR/$tdir/disable_lru_resize
10180
10181         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10182         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10183         cancel_lru_locks mdc
10184         stime=`date +%s`
10185         PID=""
10186         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10187         PID="$PID $!"
10188         sleep 2
10189         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10190         PID="$PID $!"
10191         sleep 2
10192         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10193         PID="$PID $!"
10194         wait $PID
10195         etime=`date +%s`
10196         nolruresize_delta=$((etime-stime))
10197         log "ls -la time: $nolruresize_delta seconds"
10198         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10199         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10200
10201         lru_resize_enable mdc
10202         test_mkdir -p $DIR/$tdir/enable_lru_resize
10203
10204         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10205         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10206         cancel_lru_locks mdc
10207         stime=`date +%s`
10208         PID=""
10209         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10210         PID="$PID $!"
10211         sleep 2
10212         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10213         PID="$PID $!"
10214         sleep 2
10215         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10216         PID="$PID $!"
10217         wait $PID
10218         etime=`date +%s`
10219         lruresize_delta=$((etime-stime))
10220         log "ls -la time: $lruresize_delta seconds"
10221         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10222
10223         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10224                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10225         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10226                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10227         else
10228                 log "lru resize performs the same with no lru resize"
10229         fi
10230         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10231 }
10232 run_test 124b "lru resize (performance test) ======================="
10233
10234 test_124c() {
10235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10236         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10237                 skip_env "no lru resize on server"
10238
10239         # cache ununsed locks on client
10240         local nr=100
10241         cancel_lru_locks mdc
10242         test_mkdir $DIR/$tdir
10243         createmany -o $DIR/$tdir/f $nr ||
10244                 error "failed to create $nr files in $DIR/$tdir"
10245         ls -l $DIR/$tdir > /dev/null
10246
10247         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10248         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10249         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10250         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10251         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10252
10253         # set lru_max_age to 1 sec
10254         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10255         echo "sleep $((recalc_p * 2)) seconds..."
10256         sleep $((recalc_p * 2))
10257
10258         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10259         # restore lru_max_age
10260         $LCTL set_param -n $nsdir.lru_max_age $max_age
10261         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10262         unlinkmany $DIR/$tdir/f $nr
10263 }
10264 run_test 124c "LRUR cancel very aged locks"
10265
10266 test_125() { # 13358
10267         $LCTL get_param -n llite.*.client_type | grep -q local ||
10268                 skip "must run as local client"
10269         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10270                 skip_env "must have acl enabled"
10271         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10272
10273         test_mkdir $DIR/$tdir
10274         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10275         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10276         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10277 }
10278 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10279
10280 test_126() { # bug 12829/13455
10281         $GSS && skip_env "must run as gss disabled"
10282         $LCTL get_param -n llite.*.client_type | grep -q local ||
10283                 skip "must run as local client"
10284         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10285
10286         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10287         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10288         rm -f $DIR/$tfile
10289         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10290 }
10291 run_test 126 "check that the fsgid provided by the client is taken into account"
10292
10293 test_127a() { # bug 15521
10294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10295
10296         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10297         $LCTL set_param osc.*.stats=0
10298         FSIZE=$((2048 * 1024))
10299         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10300         cancel_lru_locks osc
10301         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10302
10303         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10304         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10305                 echo "got $COUNT $NAME"
10306                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10307                 eval $NAME=$COUNT || error "Wrong proc format"
10308
10309                 case $NAME in
10310                         read_bytes|write_bytes)
10311                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10312                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10313                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10314                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10315                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10316                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10317                                 error "sumsquare is too small: $SUMSQ"
10318                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10319                                 error "sumsquare is too big: $SUMSQ"
10320                         ;;
10321                         *) ;;
10322                 esac
10323         done < $DIR/${tfile}.tmp
10324
10325         #check that we actually got some stats
10326         [ "$read_bytes" ] || error "Missing read_bytes stats"
10327         [ "$write_bytes" ] || error "Missing write_bytes stats"
10328         [ "$read_bytes" != 0 ] || error "no read done"
10329         [ "$write_bytes" != 0 ] || error "no write done"
10330 }
10331 run_test 127a "verify the client stats are sane"
10332
10333 test_127b() { # bug LU-333
10334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10335         local name count samp unit min max sum sumsq
10336
10337         $LCTL set_param llite.*.stats=0
10338
10339         # perform 2 reads and writes so MAX is different from SUM.
10340         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10341         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10342         cancel_lru_locks osc
10343         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10344         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10345
10346         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10347         while read name count samp unit min max sum sumsq; do
10348                 echo "got $count $name"
10349                 eval $name=$count || error "Wrong proc format"
10350
10351                 case $name in
10352                 read_bytes)
10353                         [ $count -ne 2 ] && error "count is not 2: $count"
10354                         [ $min -ne $PAGE_SIZE ] &&
10355                                 error "min is not $PAGE_SIZE: $min"
10356                         [ $max -ne $PAGE_SIZE ] &&
10357                                 error "max is incorrect: $max"
10358                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10359                                 error "sum is wrong: $sum"
10360                         ;;
10361                 write_bytes)
10362                         [ $count -ne 2 ] && error "count is not 2: $count"
10363                         [ $min -ne $PAGE_SIZE ] &&
10364                                 error "min is not $PAGE_SIZE: $min"
10365                         [ $max -ne $PAGE_SIZE ] &&
10366                                 error "max is incorrect: $max"
10367                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10368                                 error "sum is wrong: $sum"
10369                         ;;
10370                 *) ;;
10371                 esac
10372         done < $TMP/$tfile.tmp
10373
10374         #check that we actually got some stats
10375         [ "$read_bytes" ] || error "Missing read_bytes stats"
10376         [ "$write_bytes" ] || error "Missing write_bytes stats"
10377         [ "$read_bytes" != 0 ] || error "no read done"
10378         [ "$write_bytes" != 0 ] || error "no write done"
10379
10380         rm -f $TMP/${tfile}.tmp
10381 }
10382 run_test 127b "verify the llite client stats are sane"
10383
10384 test_128() { # bug 15212
10385         touch $DIR/$tfile
10386         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10387                 find $DIR/$tfile
10388                 find $DIR/$tfile
10389         EOF
10390
10391         result=$(grep error $TMP/$tfile.log)
10392         rm -f $DIR/$tfile $TMP/$tfile.log
10393         [ -z "$result" ] ||
10394                 error "consecutive find's under interactive lfs failed"
10395 }
10396 run_test 128 "interactive lfs for 2 consecutive find's"
10397
10398 set_dir_limits () {
10399         local mntdev
10400         local canondev
10401         local node
10402
10403         local ldproc=/proc/fs/ldiskfs
10404         local facets=$(get_facets MDS)
10405
10406         for facet in ${facets//,/ }; do
10407                 canondev=$(ldiskfs_canon \
10408                            *.$(convert_facet2label $facet).mntdev $facet)
10409                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10410                         ldproc=/sys/fs/ldiskfs
10411                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10412                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10413         done
10414 }
10415
10416 check_mds_dmesg() {
10417         local facets=$(get_facets MDS)
10418         for facet in ${facets//,/ }; do
10419                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10420         done
10421         return 1
10422 }
10423
10424 test_129() {
10425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10426         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10427                 skip "Need MDS version with at least 2.5.56"
10428         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10429                 skip_env "ldiskfs only test"
10430         fi
10431         remote_mds_nodsh && skip "remote MDS with nodsh"
10432
10433         local ENOSPC=28
10434         local EFBIG=27
10435         local has_warning=false
10436
10437         rm -rf $DIR/$tdir
10438         mkdir -p $DIR/$tdir
10439
10440         # block size of mds1
10441         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
10442         set_dir_limits $maxsize $maxsize
10443         local dirsize=$(stat -c%s "$DIR/$tdir")
10444         local nfiles=0
10445         while [[ $dirsize -le $maxsize ]]; do
10446                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
10447                 rc=$?
10448                 if ! $has_warning; then
10449                         check_mds_dmesg '"is approaching"' && has_warning=true
10450                 fi
10451                 # check two errors:
10452                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
10453                 # EFBIG for previous versions included in ldiskfs series
10454                 if [ $rc -eq $EFBIG -o $rc -eq $ENOSPC ]; then
10455                         set_dir_limits 0 0
10456                         echo "return code $rc received as expected"
10457
10458                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
10459                                 error_exit "create failed w/o dir size limit"
10460
10461                         check_mds_dmesg '"has reached"' ||
10462                                 error_exit "reached message should be output"
10463
10464                         [ $has_warning = "false" ] &&
10465                                 error_exit "warning message should be output"
10466
10467                         dirsize=$(stat -c%s "$DIR/$tdir")
10468
10469                         [[ $dirsize -ge $maxsize ]] && return 0
10470                         error_exit "current dir size $dirsize, " \
10471                                    "previous limit $maxsize"
10472                 elif [ $rc -ne 0 ]; then
10473                         set_dir_limits 0 0
10474                         error_exit "return $rc received instead of expected " \
10475                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
10476                 fi
10477                 nfiles=$((nfiles + 1))
10478                 dirsize=$(stat -c%s "$DIR/$tdir")
10479         done
10480
10481         set_dir_limits 0 0
10482         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
10483 }
10484 run_test 129 "test directory size limit ========================"
10485
10486 OLDIFS="$IFS"
10487 cleanup_130() {
10488         trap 0
10489         IFS="$OLDIFS"
10490 }
10491
10492 test_130a() {
10493         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10494         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10495
10496         trap cleanup_130 EXIT RETURN
10497
10498         local fm_file=$DIR/$tfile
10499         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
10500         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
10501                 error "dd failed for $fm_file"
10502
10503         # LU-1795: test filefrag/FIEMAP once, even if unsupported
10504         filefrag -ves $fm_file
10505         RC=$?
10506         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10507                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10508         [ $RC != 0 ] && error "filefrag $fm_file failed"
10509
10510         filefrag_op=$(filefrag -ve -k $fm_file |
10511                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10512         lun=$($LFS getstripe -i $fm_file)
10513
10514         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
10515         IFS=$'\n'
10516         tot_len=0
10517         for line in $filefrag_op
10518         do
10519                 frag_lun=`echo $line | cut -d: -f5`
10520                 ext_len=`echo $line | cut -d: -f4`
10521                 if (( $frag_lun != $lun )); then
10522                         cleanup_130
10523                         error "FIEMAP on 1-stripe file($fm_file) failed"
10524                         return
10525                 fi
10526                 (( tot_len += ext_len ))
10527         done
10528
10529         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
10530                 cleanup_130
10531                 error "FIEMAP on 1-stripe file($fm_file) failed;"
10532                 return
10533         fi
10534
10535         cleanup_130
10536
10537         echo "FIEMAP on single striped file succeeded"
10538 }
10539 run_test 130a "FIEMAP (1-stripe file)"
10540
10541 test_130b() {
10542         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
10543
10544         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10545         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10546
10547         trap cleanup_130 EXIT RETURN
10548
10549         local fm_file=$DIR/$tfile
10550         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10551                         error "setstripe on $fm_file"
10552         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10553                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10554
10555         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
10556                 error "dd failed on $fm_file"
10557
10558         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10559         filefrag_op=$(filefrag -ve -k $fm_file |
10560                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10561
10562         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10563                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10564
10565         IFS=$'\n'
10566         tot_len=0
10567         num_luns=1
10568         for line in $filefrag_op
10569         do
10570                 frag_lun=$(echo $line | cut -d: -f5 |
10571                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10572                 ext_len=$(echo $line | cut -d: -f4)
10573                 if (( $frag_lun != $last_lun )); then
10574                         if (( tot_len != 1024 )); then
10575                                 cleanup_130
10576                                 error "FIEMAP on $fm_file failed; returned " \
10577                                 "len $tot_len for OST $last_lun instead of 1024"
10578                                 return
10579                         else
10580                                 (( num_luns += 1 ))
10581                                 tot_len=0
10582                         fi
10583                 fi
10584                 (( tot_len += ext_len ))
10585                 last_lun=$frag_lun
10586         done
10587         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
10588                 cleanup_130
10589                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10590                         "luns or wrong len for OST $last_lun"
10591                 return
10592         fi
10593
10594         cleanup_130
10595
10596         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
10597 }
10598 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
10599
10600 test_130c() {
10601         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10602
10603         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10604         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10605
10606         trap cleanup_130 EXIT RETURN
10607
10608         local fm_file=$DIR/$tfile
10609         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
10610         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10611                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10612
10613         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
10614                         error "dd failed on $fm_file"
10615
10616         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10617         filefrag_op=$(filefrag -ve -k $fm_file |
10618                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10619
10620         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10621                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10622
10623         IFS=$'\n'
10624         tot_len=0
10625         num_luns=1
10626         for line in $filefrag_op
10627         do
10628                 frag_lun=$(echo $line | cut -d: -f5 |
10629                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10630                 ext_len=$(echo $line | cut -d: -f4)
10631                 if (( $frag_lun != $last_lun )); then
10632                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
10633                         if (( logical != 512 )); then
10634                                 cleanup_130
10635                                 error "FIEMAP on $fm_file failed; returned " \
10636                                 "logical start for lun $logical instead of 512"
10637                                 return
10638                         fi
10639                         if (( tot_len != 512 )); then
10640                                 cleanup_130
10641                                 error "FIEMAP on $fm_file failed; returned " \
10642                                 "len $tot_len for OST $last_lun instead of 1024"
10643                                 return
10644                         else
10645                                 (( num_luns += 1 ))
10646                                 tot_len=0
10647                         fi
10648                 fi
10649                 (( tot_len += ext_len ))
10650                 last_lun=$frag_lun
10651         done
10652         if (( num_luns != 2 || tot_len != 512 )); then
10653                 cleanup_130
10654                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10655                         "luns or wrong len for OST $last_lun"
10656                 return
10657         fi
10658
10659         cleanup_130
10660
10661         echo "FIEMAP on 2-stripe file with hole succeeded"
10662 }
10663 run_test 130c "FIEMAP (2-stripe file with hole)"
10664
10665 test_130d() {
10666         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
10667
10668         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10669         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10670
10671         trap cleanup_130 EXIT RETURN
10672
10673         local fm_file=$DIR/$tfile
10674         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10675                         error "setstripe on $fm_file"
10676         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10677                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10678
10679         local actual_stripe_count=$($LFS getstripe -c $fm_file)
10680         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
10681                 error "dd failed on $fm_file"
10682
10683         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10684         filefrag_op=$(filefrag -ve -k $fm_file |
10685                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10686
10687         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10688                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10689
10690         IFS=$'\n'
10691         tot_len=0
10692         num_luns=1
10693         for line in $filefrag_op
10694         do
10695                 frag_lun=$(echo $line | cut -d: -f5 |
10696                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10697                 ext_len=$(echo $line | cut -d: -f4)
10698                 if (( $frag_lun != $last_lun )); then
10699                         if (( tot_len != 1024 )); then
10700                                 cleanup_130
10701                                 error "FIEMAP on $fm_file failed; returned " \
10702                                 "len $tot_len for OST $last_lun instead of 1024"
10703                                 return
10704                         else
10705                                 (( num_luns += 1 ))
10706                                 tot_len=0
10707                         fi
10708                 fi
10709                 (( tot_len += ext_len ))
10710                 last_lun=$frag_lun
10711         done
10712         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
10713                 cleanup_130
10714                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10715                         "luns or wrong len for OST $last_lun"
10716                 return
10717         fi
10718
10719         cleanup_130
10720
10721         echo "FIEMAP on N-stripe file succeeded"
10722 }
10723 run_test 130d "FIEMAP (N-stripe file)"
10724
10725 test_130e() {
10726         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10727
10728         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10729         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10730
10731         trap cleanup_130 EXIT RETURN
10732
10733         local fm_file=$DIR/$tfile
10734         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
10735         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10736                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10737
10738         NUM_BLKS=512
10739         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
10740         for ((i = 0; i < $NUM_BLKS; i++))
10741         do
10742                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
10743         done
10744
10745         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10746         filefrag_op=$(filefrag -ve -k $fm_file |
10747                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10748
10749         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10750                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10751
10752         IFS=$'\n'
10753         tot_len=0
10754         num_luns=1
10755         for line in $filefrag_op
10756         do
10757                 frag_lun=$(echo $line | cut -d: -f5 |
10758                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10759                 ext_len=$(echo $line | cut -d: -f4)
10760                 if (( $frag_lun != $last_lun )); then
10761                         if (( tot_len != $EXPECTED_LEN )); then
10762                                 cleanup_130
10763                                 error "FIEMAP on $fm_file failed; returned " \
10764                                 "len $tot_len for OST $last_lun instead " \
10765                                 "of $EXPECTED_LEN"
10766                                 return
10767                         else
10768                                 (( num_luns += 1 ))
10769                                 tot_len=0
10770                         fi
10771                 fi
10772                 (( tot_len += ext_len ))
10773                 last_lun=$frag_lun
10774         done
10775         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
10776                 cleanup_130
10777                 error "FIEMAP on $fm_file failed; returned wrong number " \
10778                         "of luns or wrong len for OST $last_lun"
10779                 return
10780         fi
10781
10782         cleanup_130
10783
10784         echo "FIEMAP with continuation calls succeeded"
10785 }
10786 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
10787
10788 test_130f() {
10789         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10790         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10791
10792         local fm_file=$DIR/$tfile
10793         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
10794                 error "multiop create with lov_delay_create on $fm_file"
10795
10796         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10797         filefrag_extents=$(filefrag -vek $fm_file |
10798                            awk '/extents? found/ { print $2 }')
10799         if [[ "$filefrag_extents" != "0" ]]; then
10800                 error "FIEMAP on $fm_file failed; " \
10801                       "returned $filefrag_extents expected 0"
10802         fi
10803
10804         rm -f $fm_file
10805 }
10806 run_test 130f "FIEMAP (unstriped file)"
10807
10808 # Test for writev/readv
10809 test_131a() {
10810         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
10811                 error "writev test failed"
10812         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
10813                 error "readv failed"
10814         rm -f $DIR/$tfile
10815 }
10816 run_test 131a "test iov's crossing stripe boundary for writev/readv"
10817
10818 test_131b() {
10819         local fsize=$((524288 + 1048576 + 1572864))
10820         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
10821                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10822                         error "append writev test failed"
10823
10824         ((fsize += 1572864 + 1048576))
10825         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
10826                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10827                         error "append writev test failed"
10828         rm -f $DIR/$tfile
10829 }
10830 run_test 131b "test append writev"
10831
10832 test_131c() {
10833         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
10834         error "NOT PASS"
10835 }
10836 run_test 131c "test read/write on file w/o objects"
10837
10838 test_131d() {
10839         rwv -f $DIR/$tfile -w -n 1 1572864
10840         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
10841         if [ "$NOB" != 1572864 ]; then
10842                 error "Short read filed: read $NOB bytes instead of 1572864"
10843         fi
10844         rm -f $DIR/$tfile
10845 }
10846 run_test 131d "test short read"
10847
10848 test_131e() {
10849         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
10850         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
10851         error "read hitting hole failed"
10852         rm -f $DIR/$tfile
10853 }
10854 run_test 131e "test read hitting hole"
10855
10856 check_stats() {
10857         local facet=$1
10858         local op=$2
10859         local want=${3:-0}
10860         local res
10861
10862         case $facet in
10863         mds*) res=$(do_facet $facet \
10864                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
10865                  ;;
10866         ost*) res=$(do_facet $facet \
10867                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
10868                  ;;
10869         *) error "Wrong facet '$facet'" ;;
10870         esac
10871         [ "$res" ] || error "The counter for $op on $facet was not incremented"
10872         # if the argument $3 is zero, it means any stat increment is ok.
10873         if [[ $want -gt 0 ]]; then
10874                 local count=$(echo $res | awk '{ print $2 }')
10875                 [[ $count -ne $want ]] &&
10876                         error "The $op counter on $facet is $count, not $want"
10877         fi
10878 }
10879
10880 test_133a() {
10881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10882         remote_ost_nodsh && skip "remote OST with nodsh"
10883         remote_mds_nodsh && skip "remote MDS with nodsh"
10884         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
10885                 skip_env "MDS doesn't support rename stats"
10886
10887         local testdir=$DIR/${tdir}/stats_testdir
10888
10889         mkdir -p $DIR/${tdir}
10890
10891         # clear stats.
10892         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10893         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10894
10895         # verify mdt stats first.
10896         mkdir ${testdir} || error "mkdir failed"
10897         check_stats $SINGLEMDS "mkdir" 1
10898         touch ${testdir}/${tfile} || error "touch failed"
10899         check_stats $SINGLEMDS "open" 1
10900         check_stats $SINGLEMDS "close" 1
10901         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
10902                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
10903                 check_stats $SINGLEMDS "mknod" 2
10904         }
10905         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
10906         check_stats $SINGLEMDS "unlink" 1
10907         rm -f ${testdir}/${tfile} || error "file remove failed"
10908         check_stats $SINGLEMDS "unlink" 2
10909
10910         # remove working dir and check mdt stats again.
10911         rmdir ${testdir} || error "rmdir failed"
10912         check_stats $SINGLEMDS "rmdir" 1
10913
10914         local testdir1=$DIR/${tdir}/stats_testdir1
10915         mkdir -p ${testdir}
10916         mkdir -p ${testdir1}
10917         touch ${testdir1}/test1
10918         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
10919         check_stats $SINGLEMDS "crossdir_rename" 1
10920
10921         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
10922         check_stats $SINGLEMDS "samedir_rename" 1
10923
10924         rm -rf $DIR/${tdir}
10925 }
10926 run_test 133a "Verifying MDT stats ========================================"
10927
10928 test_133b() {
10929         local res
10930
10931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10932         remote_ost_nodsh && skip "remote OST with nodsh"
10933         remote_mds_nodsh && skip "remote MDS with nodsh"
10934
10935         local testdir=$DIR/${tdir}/stats_testdir
10936
10937         mkdir -p ${testdir} || error "mkdir failed"
10938         touch ${testdir}/${tfile} || error "touch failed"
10939         cancel_lru_locks mdc
10940
10941         # clear stats.
10942         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10943         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10944
10945         # extra mdt stats verification.
10946         chmod 444 ${testdir}/${tfile} || error "chmod failed"
10947         check_stats $SINGLEMDS "setattr" 1
10948         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10949         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
10950         then            # LU-1740
10951                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
10952                 check_stats $SINGLEMDS "getattr" 1
10953         fi
10954         rm -rf $DIR/${tdir}
10955
10956         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
10957         # so the check below is not reliable
10958         [ $MDSCOUNT -eq 1 ] || return 0
10959
10960         # Sleep to avoid a cached response.
10961         #define OBD_STATFS_CACHE_SECONDS 1
10962         sleep 2
10963         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10964         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
10965         $LFS df || error "lfs failed"
10966         check_stats $SINGLEMDS "statfs" 1
10967
10968         # check aggregated statfs (LU-10018)
10969         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
10970                 return 0
10971         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
10972                 return 0
10973         sleep 2
10974         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10975         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
10976         df $DIR
10977         check_stats $SINGLEMDS "statfs" 1
10978
10979         # We want to check that the client didn't send OST_STATFS to
10980         # ost1 but the MDT also uses OST_STATFS for precreate. So some
10981         # extra care is needed here.
10982         if remote_mds; then
10983                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
10984                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
10985
10986                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
10987                 [ "$res" ] && error "OST got STATFS"
10988         fi
10989
10990         return 0
10991 }
10992 run_test 133b "Verifying extra MDT stats =================================="
10993
10994 test_133c() {
10995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10996         remote_ost_nodsh && skip "remote OST with nodsh"
10997         remote_mds_nodsh && skip "remote MDS with nodsh"
10998
10999         local testdir=$DIR/$tdir/stats_testdir
11000
11001         test_mkdir -p $testdir
11002
11003         # verify obdfilter stats.
11004         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11005         sync
11006         cancel_lru_locks osc
11007         wait_delete_completed
11008
11009         # clear stats.
11010         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11011         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11012
11013         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11014                 error "dd failed"
11015         sync
11016         cancel_lru_locks osc
11017         check_stats ost1 "write" 1
11018
11019         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11020         check_stats ost1 "read" 1
11021
11022         > $testdir/$tfile || error "truncate failed"
11023         check_stats ost1 "punch" 1
11024
11025         rm -f $testdir/$tfile || error "file remove failed"
11026         wait_delete_completed
11027         check_stats ost1 "destroy" 1
11028
11029         rm -rf $DIR/$tdir
11030 }
11031 run_test 133c "Verifying OST stats ========================================"
11032
11033 order_2() {
11034         local value=$1
11035         local orig=$value
11036         local order=1
11037
11038         while [ $value -ge 2 ]; do
11039                 order=$((order*2))
11040                 value=$((value/2))
11041         done
11042
11043         if [ $orig -gt $order ]; then
11044                 order=$((order*2))
11045         fi
11046         echo $order
11047 }
11048
11049 size_in_KMGT() {
11050     local value=$1
11051     local size=('K' 'M' 'G' 'T');
11052     local i=0
11053     local size_string=$value
11054
11055     while [ $value -ge 1024 ]; do
11056         if [ $i -gt 3 ]; then
11057             #T is the biggest unit we get here, if that is bigger,
11058             #just return XXXT
11059             size_string=${value}T
11060             break
11061         fi
11062         value=$((value >> 10))
11063         if [ $value -lt 1024 ]; then
11064             size_string=${value}${size[$i]}
11065             break
11066         fi
11067         i=$((i + 1))
11068     done
11069
11070     echo $size_string
11071 }
11072
11073 get_rename_size() {
11074         local size=$1
11075         local context=${2:-.}
11076         local sample=$(do_facet $SINGLEMDS $LCTL \
11077                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11078                 grep -A1 $context |
11079                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11080         echo $sample
11081 }
11082
11083 test_133d() {
11084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11085         remote_ost_nodsh && skip "remote OST with nodsh"
11086         remote_mds_nodsh && skip "remote MDS with nodsh"
11087         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11088                 skip_env "MDS doesn't support rename stats"
11089
11090         local testdir1=$DIR/${tdir}/stats_testdir1
11091         local testdir2=$DIR/${tdir}/stats_testdir2
11092         mkdir -p $DIR/${tdir}
11093
11094         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11095
11096         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11097         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11098
11099         createmany -o $testdir1/test 512 || error "createmany failed"
11100
11101         # check samedir rename size
11102         mv ${testdir1}/test0 ${testdir1}/test_0
11103
11104         local testdir1_size=$(ls -l $DIR/${tdir} |
11105                 awk '/stats_testdir1/ {print $5}')
11106         local testdir2_size=$(ls -l $DIR/${tdir} |
11107                 awk '/stats_testdir2/ {print $5}')
11108
11109         testdir1_size=$(order_2 $testdir1_size)
11110         testdir2_size=$(order_2 $testdir2_size)
11111
11112         testdir1_size=$(size_in_KMGT $testdir1_size)
11113         testdir2_size=$(size_in_KMGT $testdir2_size)
11114
11115         echo "source rename dir size: ${testdir1_size}"
11116         echo "target rename dir size: ${testdir2_size}"
11117
11118         local cmd="do_facet $SINGLEMDS $LCTL "
11119         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11120
11121         eval $cmd || error "$cmd failed"
11122         local samedir=$($cmd | grep 'same_dir')
11123         local same_sample=$(get_rename_size $testdir1_size)
11124         [ -z "$samedir" ] && error "samedir_rename_size count error"
11125         [[ $same_sample -eq 1 ]] ||
11126                 error "samedir_rename_size error $same_sample"
11127         echo "Check same dir rename stats success"
11128
11129         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11130
11131         # check crossdir rename size
11132         mv ${testdir1}/test_0 ${testdir2}/test_0
11133
11134         testdir1_size=$(ls -l $DIR/${tdir} |
11135                 awk '/stats_testdir1/ {print $5}')
11136         testdir2_size=$(ls -l $DIR/${tdir} |
11137                 awk '/stats_testdir2/ {print $5}')
11138
11139         testdir1_size=$(order_2 $testdir1_size)
11140         testdir2_size=$(order_2 $testdir2_size)
11141
11142         testdir1_size=$(size_in_KMGT $testdir1_size)
11143         testdir2_size=$(size_in_KMGT $testdir2_size)
11144
11145         echo "source rename dir size: ${testdir1_size}"
11146         echo "target rename dir size: ${testdir2_size}"
11147
11148         eval $cmd || error "$cmd failed"
11149         local crossdir=$($cmd | grep 'crossdir')
11150         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11151         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11152         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11153         [[ $src_sample -eq 1 ]] ||
11154                 error "crossdir_rename_size error $src_sample"
11155         [[ $tgt_sample -eq 1 ]] ||
11156                 error "crossdir_rename_size error $tgt_sample"
11157         echo "Check cross dir rename stats success"
11158         rm -rf $DIR/${tdir}
11159 }
11160 run_test 133d "Verifying rename_stats ========================================"
11161
11162 test_133e() {
11163         remote_mds_nodsh && skip "remote MDS with nodsh"
11164         remote_ost_nodsh && skip "remote OST with nodsh"
11165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11166
11167         local testdir=$DIR/${tdir}/stats_testdir
11168         local ctr f0 f1 bs=32768 count=42 sum
11169
11170         mkdir -p ${testdir} || error "mkdir failed"
11171
11172         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11173
11174         for ctr in {write,read}_bytes; do
11175                 sync
11176                 cancel_lru_locks osc
11177
11178                 do_facet ost1 $LCTL set_param -n \
11179                         "obdfilter.*.exports.clear=clear"
11180
11181                 if [ $ctr = write_bytes ]; then
11182                         f0=/dev/zero
11183                         f1=${testdir}/${tfile}
11184                 else
11185                         f0=${testdir}/${tfile}
11186                         f1=/dev/null
11187                 fi
11188
11189                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11190                         error "dd failed"
11191                 sync
11192                 cancel_lru_locks osc
11193
11194                 sum=$(do_facet ost1 $LCTL get_param \
11195                         "obdfilter.*.exports.*.stats" |
11196                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11197                                 $1 == ctr { sum += $7 }
11198                                 END { printf("%0.0f", sum) }')
11199
11200                 if ((sum != bs * count)); then
11201                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11202                 fi
11203         done
11204
11205         rm -rf $DIR/${tdir}
11206 }
11207 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11208
11209 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11210
11211 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11212 # not honor the -ignore_readdir_race option correctly. So we call
11213 # error_ignore() rather than error() in these cases. See LU-11152.
11214 error_133() {
11215         if (find --version; do_facet mds1 find --version) |
11216                 grep -q '\b4\.5\.1[1-4]\b'; then
11217                 error_ignore LU-11152 "$@"
11218         else
11219                 error "$@"
11220         fi
11221 }
11222
11223 test_133f() {
11224         # First without trusting modes.
11225         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11226         echo "proc_dirs='$proc_dirs'"
11227         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11228         find $proc_dirs -exec cat '{}' \; &> /dev/null
11229
11230         # Second verifying readability.
11231         $LCTL get_param -R '*' &> /dev/null
11232
11233         # Verifing writability with badarea_io.
11234         find $proc_dirs \
11235                 -ignore_readdir_race \
11236                 -type f \
11237                 -not -name force_lbug \
11238                 -not -name changelog_mask \
11239                 -exec badarea_io '{}' \; ||
11240                         error_133 "find $proc_dirs failed"
11241 }
11242 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11243
11244 test_133g() {
11245         remote_mds_nodsh && skip "remote MDS with nodsh"
11246         remote_ost_nodsh && skip "remote OST with nodsh"
11247
11248         # eventually, this can also be replaced with "lctl get_param -R",
11249         # but not until that option is always available on the server
11250         local facet
11251         for facet in mds1 ost1; do
11252                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11253                         skip_noexit "Too old lustre on $facet"
11254                 local facet_proc_dirs=$(do_facet $facet \
11255                                         \\\ls -d $proc_regexp 2>/dev/null)
11256                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11257                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11258                 do_facet $facet find $facet_proc_dirs \
11259                         ! -name req_history \
11260                         -exec cat '{}' \\\; &> /dev/null
11261
11262                 do_facet $facet find $facet_proc_dirs \
11263                         ! -name req_history \
11264                         -type f \
11265                         -exec cat '{}' \\\; &> /dev/null ||
11266                                 error "proc file read failed"
11267
11268                 do_facet $facet find $facet_proc_dirs \
11269                         -ignore_readdir_race \
11270                         -type f \
11271                         -not -name force_lbug \
11272                         -not -name changelog_mask \
11273                         -exec badarea_io '{}' \\\; ||
11274                                 error_133 "$facet find $facet_proc_dirs failed"
11275         done
11276
11277         # remount the FS in case writes/reads /proc break the FS
11278         cleanup || error "failed to unmount"
11279         setup || error "failed to setup"
11280         true
11281 }
11282 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11283
11284 test_133h() {
11285         remote_mds_nodsh && skip "remote MDS with nodsh"
11286         remote_ost_nodsh && skip "remote OST with nodsh"
11287         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11288                 skip "Need MDS version at least 2.9.54"
11289
11290         local facet
11291
11292         for facet in client mds1 ost1; do
11293                 local facet_proc_dirs=$(do_facet $facet \
11294                                         \\\ls -d $proc_regexp 2> /dev/null)
11295                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11296                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11297                 # Get the list of files that are missing the terminating newline
11298                 local missing=($(do_facet $facet \
11299                         find ${facet_proc_dirs} -type f \|              \
11300                                 while read F\; do                       \
11301                                         awk -v FS='\v' -v RS='\v\v'     \
11302                                         "'END { if(NR>0 &&              \
11303                                         \\\$NF !~ /.*\\\n\$/)           \
11304                                                 print FILENAME}'"       \
11305                                         '\$F'\;                         \
11306                                 done 2>/dev/null))
11307                 [ ${#missing[*]} -eq 0 ] ||
11308                         error "files do not end with newline: ${missing[*]}"
11309         done
11310 }
11311 run_test 133h "Proc files should end with newlines"
11312
11313 test_134a() {
11314         remote_mds_nodsh && skip "remote MDS with nodsh"
11315         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11316                 skip "Need MDS version at least 2.7.54"
11317
11318         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11319         cancel_lru_locks mdc
11320
11321         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11322         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11323         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11324
11325         local nr=1000
11326         createmany -o $DIR/$tdir/f $nr ||
11327                 error "failed to create $nr files in $DIR/$tdir"
11328         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11329
11330         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11331         do_facet mds1 $LCTL set_param fail_loc=0x327
11332         do_facet mds1 $LCTL set_param fail_val=500
11333         touch $DIR/$tdir/m
11334
11335         echo "sleep 10 seconds ..."
11336         sleep 10
11337         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11338
11339         do_facet mds1 $LCTL set_param fail_loc=0
11340         do_facet mds1 $LCTL set_param fail_val=0
11341         [ $lck_cnt -lt $unused ] ||
11342                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11343
11344         rm $DIR/$tdir/m
11345         unlinkmany $DIR/$tdir/f $nr
11346 }
11347 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11348
11349 test_134b() {
11350         remote_mds_nodsh && skip "remote MDS with nodsh"
11351         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11352                 skip "Need MDS version at least 2.7.54"
11353
11354         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11355         cancel_lru_locks mdc
11356
11357         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11358                         ldlm.lock_reclaim_threshold_mb)
11359         # disable reclaim temporarily
11360         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11361
11362         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11363         do_facet mds1 $LCTL set_param fail_loc=0x328
11364         do_facet mds1 $LCTL set_param fail_val=500
11365
11366         $LCTL set_param debug=+trace
11367
11368         local nr=600
11369         createmany -o $DIR/$tdir/f $nr &
11370         local create_pid=$!
11371
11372         echo "Sleep $TIMEOUT seconds ..."
11373         sleep $TIMEOUT
11374         if ! ps -p $create_pid  > /dev/null 2>&1; then
11375                 do_facet mds1 $LCTL set_param fail_loc=0
11376                 do_facet mds1 $LCTL set_param fail_val=0
11377                 do_facet mds1 $LCTL set_param \
11378                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11379                 error "createmany finished incorrectly!"
11380         fi
11381         do_facet mds1 $LCTL set_param fail_loc=0
11382         do_facet mds1 $LCTL set_param fail_val=0
11383         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11384         wait $create_pid || return 1
11385
11386         unlinkmany $DIR/$tdir/f $nr
11387 }
11388 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11389
11390 test_140() { #bug-17379
11391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11392
11393         test_mkdir $DIR/$tdir
11394         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11395         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11396
11397         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11398         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11399         local i=0
11400         while i=$((i + 1)); do
11401                 test_mkdir $i
11402                 cd $i || error "Changing to $i"
11403                 ln -s ../stat stat || error "Creating stat symlink"
11404                 # Read the symlink until ELOOP present,
11405                 # not LBUGing the system is considered success,
11406                 # we didn't overrun the stack.
11407                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11408                 if [ $ret -ne 0 ]; then
11409                         if [ $ret -eq 40 ]; then
11410                                 break  # -ELOOP
11411                         else
11412                                 error "Open stat symlink"
11413                                         return
11414                         fi
11415                 fi
11416         done
11417         i=$((i - 1))
11418         echo "The symlink depth = $i"
11419         [ $i -eq 5 -o $i -eq 7 -o $i -eq 8 -o $i -eq 40 ] ||
11420                                         error "Invalid symlink depth"
11421
11422         # Test recursive symlink
11423         ln -s symlink_self symlink_self
11424         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11425         echo "open symlink_self returns $ret"
11426         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11427 }
11428 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11429
11430 test_150() {
11431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11432
11433         local TF="$TMP/$tfile"
11434
11435         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11436         cp $TF $DIR/$tfile
11437         cancel_lru_locks $OSC
11438         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
11439         remount_client $MOUNT
11440         df -P $MOUNT
11441         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
11442
11443         $TRUNCATE $TF 6000
11444         $TRUNCATE $DIR/$tfile 6000
11445         cancel_lru_locks $OSC
11446         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
11447
11448         echo "12345" >>$TF
11449         echo "12345" >>$DIR/$tfile
11450         cancel_lru_locks $OSC
11451         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
11452
11453         echo "12345" >>$TF
11454         echo "12345" >>$DIR/$tfile
11455         cancel_lru_locks $OSC
11456         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
11457
11458         rm -f $TF
11459         true
11460 }
11461 run_test 150 "truncate/append tests"
11462
11463 #LU-2902 roc_hit was not able to read all values from lproc
11464 function roc_hit_init() {
11465         local list=$(comma_list $(osts_nodes))
11466         local dir=$DIR/$tdir-check
11467         local file=$dir/$tfile
11468         local BEFORE
11469         local AFTER
11470         local idx
11471
11472         test_mkdir $dir
11473         #use setstripe to do a write to every ost
11474         for i in $(seq 0 $((OSTCOUNT-1))); do
11475                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
11476                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
11477                 idx=$(printf %04x $i)
11478                 BEFORE=$(get_osd_param $list *OST*$idx stats |
11479                         awk '$1 == "cache_access" {sum += $7}
11480                                 END { printf("%0.0f", sum) }')
11481
11482                 cancel_lru_locks osc
11483                 cat $file >/dev/null
11484
11485                 AFTER=$(get_osd_param $list *OST*$idx stats |
11486                         awk '$1 == "cache_access" {sum += $7}
11487                                 END { printf("%0.0f", sum) }')
11488
11489                 echo BEFORE:$BEFORE AFTER:$AFTER
11490                 if ! let "AFTER - BEFORE == 4"; then
11491                         rm -rf $dir
11492                         error "roc_hit is not safe to use"
11493                 fi
11494                 rm $file
11495         done
11496
11497         rm -rf $dir
11498 }
11499
11500 function roc_hit() {
11501         local list=$(comma_list $(osts_nodes))
11502         echo $(get_osd_param $list '' stats |
11503                 awk '$1 == "cache_hit" {sum += $7}
11504                         END { printf("%0.0f", sum) }')
11505 }
11506
11507 function set_cache() {
11508         local on=1
11509
11510         if [ "$2" == "off" ]; then
11511                 on=0;
11512         fi
11513         local list=$(comma_list $(osts_nodes))
11514         set_osd_param $list '' $1_cache_enable $on
11515
11516         cancel_lru_locks osc
11517 }
11518
11519 test_151() {
11520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11521         remote_ost_nodsh && skip "remote OST with nodsh"
11522
11523         local CPAGES=3
11524         local list=$(comma_list $(osts_nodes))
11525
11526         # check whether obdfilter is cache capable at all
11527         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
11528                 skip "not cache-capable obdfilter"
11529         fi
11530
11531         # check cache is enabled on all obdfilters
11532         if get_osd_param $list '' read_cache_enable | grep 0; then
11533                 skip "oss cache is disabled"
11534         fi
11535
11536         set_osd_param $list '' writethrough_cache_enable 1
11537
11538         # check write cache is enabled on all obdfilters
11539         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
11540                 skip "oss write cache is NOT enabled"
11541         fi
11542
11543         roc_hit_init
11544
11545         #define OBD_FAIL_OBD_NO_LRU  0x609
11546         do_nodes $list $LCTL set_param fail_loc=0x609
11547
11548         # pages should be in the case right after write
11549         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
11550                 error "dd failed"
11551
11552         local BEFORE=$(roc_hit)
11553         cancel_lru_locks osc
11554         cat $DIR/$tfile >/dev/null
11555         local AFTER=$(roc_hit)
11556
11557         do_nodes $list $LCTL set_param fail_loc=0
11558
11559         if ! let "AFTER - BEFORE == CPAGES"; then
11560                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11561         fi
11562
11563         # the following read invalidates the cache
11564         cancel_lru_locks osc
11565         set_osd_param $list '' read_cache_enable 0
11566         cat $DIR/$tfile >/dev/null
11567
11568         # now data shouldn't be found in the cache
11569         BEFORE=$(roc_hit)
11570         cancel_lru_locks osc
11571         cat $DIR/$tfile >/dev/null
11572         AFTER=$(roc_hit)
11573         if let "AFTER - BEFORE != 0"; then
11574                 error "IN CACHE: before: $BEFORE, after: $AFTER"
11575         fi
11576
11577         set_osd_param $list '' read_cache_enable 1
11578         rm -f $DIR/$tfile
11579 }
11580 run_test 151 "test cache on oss and controls ==============================="
11581
11582 test_152() {
11583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11584
11585         local TF="$TMP/$tfile"
11586
11587         # simulate ENOMEM during write
11588 #define OBD_FAIL_OST_NOMEM      0x226
11589         lctl set_param fail_loc=0x80000226
11590         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11591         cp $TF $DIR/$tfile
11592         sync || error "sync failed"
11593         lctl set_param fail_loc=0
11594
11595         # discard client's cache
11596         cancel_lru_locks osc
11597
11598         # simulate ENOMEM during read
11599         lctl set_param fail_loc=0x80000226
11600         cmp $TF $DIR/$tfile || error "cmp failed"
11601         lctl set_param fail_loc=0
11602
11603         rm -f $TF
11604 }
11605 run_test 152 "test read/write with enomem ============================"
11606
11607 test_153() {
11608         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
11609 }
11610 run_test 153 "test if fdatasync does not crash ======================="
11611
11612 dot_lustre_fid_permission_check() {
11613         local fid=$1
11614         local ffid=$MOUNT/.lustre/fid/$fid
11615         local test_dir=$2
11616
11617         echo "stat fid $fid"
11618         stat $ffid > /dev/null || error "stat $ffid failed."
11619         echo "touch fid $fid"
11620         touch $ffid || error "touch $ffid failed."
11621         echo "write to fid $fid"
11622         cat /etc/hosts > $ffid || error "write $ffid failed."
11623         echo "read fid $fid"
11624         diff /etc/hosts $ffid || error "read $ffid failed."
11625         echo "append write to fid $fid"
11626         cat /etc/hosts >> $ffid || error "append write $ffid failed."
11627         echo "rename fid $fid"
11628         mv $ffid $test_dir/$tfile.1 &&
11629                 error "rename $ffid to $tfile.1 should fail."
11630         touch $test_dir/$tfile.1
11631         mv $test_dir/$tfile.1 $ffid &&
11632                 error "rename $tfile.1 to $ffid should fail."
11633         rm -f $test_dir/$tfile.1
11634         echo "truncate fid $fid"
11635         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
11636         echo "link fid $fid"
11637         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
11638         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
11639                 echo "setfacl fid $fid"
11640                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
11641                 echo "getfacl fid $fid"
11642                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
11643         fi
11644         echo "unlink fid $fid"
11645         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
11646         echo "mknod fid $fid"
11647         mknod $ffid c 1 3 && error "mknod $ffid should fail."
11648
11649         fid=[0xf00000400:0x1:0x0]
11650         ffid=$MOUNT/.lustre/fid/$fid
11651
11652         echo "stat non-exist fid $fid"
11653         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
11654         echo "write to non-exist fid $fid"
11655         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
11656         echo "link new fid $fid"
11657         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
11658
11659         mkdir -p $test_dir/$tdir
11660         touch $test_dir/$tdir/$tfile
11661         fid=$($LFS path2fid $test_dir/$tdir)
11662         rc=$?
11663         [ $rc -ne 0 ] &&
11664                 error "error: could not get fid for $test_dir/$dir/$tfile."
11665
11666         ffid=$MOUNT/.lustre/fid/$fid
11667
11668         echo "ls $fid"
11669         ls $ffid > /dev/null || error "ls $ffid failed."
11670         echo "touch $fid/$tfile.1"
11671         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
11672
11673         echo "touch $MOUNT/.lustre/fid/$tfile"
11674         touch $MOUNT/.lustre/fid/$tfile && \
11675                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
11676
11677         echo "setxattr to $MOUNT/.lustre/fid"
11678         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
11679
11680         echo "listxattr for $MOUNT/.lustre/fid"
11681         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
11682
11683         echo "delxattr from $MOUNT/.lustre/fid"
11684         setfattr -x trusted.name1 $MOUNT/.lustre/fid
11685
11686         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
11687         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
11688                 error "touch invalid fid should fail."
11689
11690         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
11691         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
11692                 error "touch non-normal fid should fail."
11693
11694         echo "rename $tdir to $MOUNT/.lustre/fid"
11695         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
11696                 error "rename to $MOUNT/.lustre/fid should fail."
11697
11698         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
11699         then            # LU-3547
11700                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
11701                 local new_obf_mode=777
11702
11703                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
11704                 chmod $new_obf_mode $DIR/.lustre/fid ||
11705                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
11706
11707                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
11708                 [ $obf_mode -eq $new_obf_mode ] ||
11709                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
11710
11711                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
11712                 chmod $old_obf_mode $DIR/.lustre/fid ||
11713                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
11714         fi
11715
11716         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
11717         fid=$($LFS path2fid $test_dir/$tfile-2)
11718
11719         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
11720         then # LU-5424
11721                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
11722                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
11723                         error "create lov data thru .lustre failed"
11724         fi
11725         echo "cp /etc/passwd $test_dir/$tfile-2"
11726         cp /etc/passwd $test_dir/$tfile-2 ||
11727                 error "copy to $test_dir/$tfile-2 failed."
11728         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
11729         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
11730                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
11731
11732         rm -rf $test_dir/tfile.lnk
11733         rm -rf $test_dir/$tfile-2
11734 }
11735
11736 test_154A() {
11737         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11738                 skip "Need MDS version at least 2.4.1"
11739
11740         local tf=$DIR/$tfile
11741         touch $tf
11742
11743         local fid=$($LFS path2fid $tf)
11744         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
11745
11746         # check that we get the same pathname back
11747         local found=$($LFS fid2path $MOUNT "$fid")
11748         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
11749         [ "$found" == "$tf" ] ||
11750                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
11751 }
11752 run_test 154A "lfs path2fid and fid2path basic checks"
11753
11754 test_154B() {
11755         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11756                 skip "Need MDS version at least 2.4.1"
11757
11758         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
11759         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
11760         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
11761         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
11762
11763         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
11764         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
11765
11766         # check that we get the same pathname
11767         echo "PFID: $PFID, name: $name"
11768         local FOUND=$($LFS fid2path $MOUNT "$PFID")
11769         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
11770         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
11771                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
11772
11773         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
11774 }
11775 run_test 154B "verify the ll_decode_linkea tool"
11776
11777 test_154a() {
11778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11779         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11780         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11781                 skip "Need MDS version at least 2.2.51"
11782         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11783
11784         cp /etc/hosts $DIR/$tfile
11785
11786         fid=$($LFS path2fid $DIR/$tfile)
11787         rc=$?
11788         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
11789
11790         dot_lustre_fid_permission_check "$fid" $DIR ||
11791                 error "dot lustre permission check $fid failed"
11792
11793         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
11794
11795         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
11796
11797         touch $MOUNT/.lustre/file &&
11798                 error "creation is not allowed under .lustre"
11799
11800         mkdir $MOUNT/.lustre/dir &&
11801                 error "mkdir is not allowed under .lustre"
11802
11803         rm -rf $DIR/$tfile
11804 }
11805 run_test 154a "Open-by-FID"
11806
11807 test_154b() {
11808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11809         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11810         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
11811         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11812                 skip "Need MDS version at least 2.2.51"
11813
11814         local remote_dir=$DIR/$tdir/remote_dir
11815         local MDTIDX=1
11816         local rc=0
11817
11818         mkdir -p $DIR/$tdir
11819         $LFS mkdir -i $MDTIDX $remote_dir ||
11820                 error "create remote directory failed"
11821
11822         cp /etc/hosts $remote_dir/$tfile
11823
11824         fid=$($LFS path2fid $remote_dir/$tfile)
11825         rc=$?
11826         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
11827
11828         dot_lustre_fid_permission_check "$fid" $remote_dir ||
11829                 error "dot lustre permission check $fid failed"
11830         rm -rf $DIR/$tdir
11831 }
11832 run_test 154b "Open-by-FID for remote directory"
11833
11834 test_154c() {
11835         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11836                 skip "Need MDS version at least 2.4.1"
11837
11838         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
11839         local FID1=$($LFS path2fid $DIR/$tfile.1)
11840         local FID2=$($LFS path2fid $DIR/$tfile.2)
11841         local FID3=$($LFS path2fid $DIR/$tfile.3)
11842
11843         local N=1
11844         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
11845                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
11846                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
11847                 local want=FID$N
11848                 [ "$FID" = "${!want}" ] ||
11849                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
11850                 N=$((N + 1))
11851         done
11852
11853         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
11854         do
11855                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
11856                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
11857                 N=$((N + 1))
11858         done
11859 }
11860 run_test 154c "lfs path2fid and fid2path multiple arguments"
11861
11862 test_154d() {
11863         remote_mds_nodsh && skip "remote MDS with nodsh"
11864         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
11865                 skip "Need MDS version at least 2.5.53"
11866
11867         if remote_mds; then
11868                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
11869         else
11870                 nid="0@lo"
11871         fi
11872         local proc_ofile="mdt.*.exports.'$nid'.open_files"
11873         local fd
11874         local cmd
11875
11876         rm -f $DIR/$tfile
11877         touch $DIR/$tfile
11878
11879         local fid=$($LFS path2fid $DIR/$tfile)
11880         # Open the file
11881         fd=$(free_fd)
11882         cmd="exec $fd<$DIR/$tfile"
11883         eval $cmd
11884         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
11885         echo "$fid_list" | grep "$fid"
11886         rc=$?
11887
11888         cmd="exec $fd>/dev/null"
11889         eval $cmd
11890         if [ $rc -ne 0 ]; then
11891                 error "FID $fid not found in open files list $fid_list"
11892         fi
11893 }
11894 run_test 154d "Verify open file fid"
11895
11896 test_154e()
11897 {
11898         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
11899                 skip "Need MDS version at least 2.6.50"
11900
11901         if ls -a $MOUNT | grep -q '^\.lustre$'; then
11902                 error ".lustre returned by readdir"
11903         fi
11904 }
11905 run_test 154e ".lustre is not returned by readdir"
11906
11907 test_154f() {
11908         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11909
11910         # create parent directory on a single MDT to avoid cross-MDT hardlinks
11911         test_mkdir -p -c1 $DIR/$tdir/d
11912         # test dirs inherit from its stripe
11913         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
11914         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
11915         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
11916         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
11917         touch $DIR/f
11918
11919         # get fid of parents
11920         local FID0=$($LFS path2fid $DIR/$tdir/d)
11921         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
11922         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
11923         local FID3=$($LFS path2fid $DIR)
11924
11925         # check that path2fid --parents returns expected <parent_fid>/name
11926         # 1) test for a directory (single parent)
11927         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
11928         [ "$parent" == "$FID0/foo1" ] ||
11929                 error "expected parent: $FID0/foo1, got: $parent"
11930
11931         # 2) test for a file with nlink > 1 (multiple parents)
11932         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
11933         echo "$parent" | grep -F "$FID1/$tfile" ||
11934                 error "$FID1/$tfile not returned in parent list"
11935         echo "$parent" | grep -F "$FID2/link" ||
11936                 error "$FID2/link not returned in parent list"
11937
11938         # 3) get parent by fid
11939         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
11940         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
11941         echo "$parent" | grep -F "$FID1/$tfile" ||
11942                 error "$FID1/$tfile not returned in parent list (by fid)"
11943         echo "$parent" | grep -F "$FID2/link" ||
11944                 error "$FID2/link not returned in parent list (by fid)"
11945
11946         # 4) test for entry in root directory
11947         parent=$($LFS path2fid --parents $DIR/f)
11948         echo "$parent" | grep -F "$FID3/f" ||
11949                 error "$FID3/f not returned in parent list"
11950
11951         # 5) test it on root directory
11952         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
11953                 error "$MOUNT should not have parents"
11954
11955         # enable xattr caching and check that linkea is correctly updated
11956         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11957         save_lustre_params client "llite.*.xattr_cache" > $save
11958         lctl set_param llite.*.xattr_cache 1
11959
11960         # 6.1) linkea update on rename
11961         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
11962
11963         # get parents by fid
11964         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
11965         # foo1 should no longer be returned in parent list
11966         echo "$parent" | grep -F "$FID1" &&
11967                 error "$FID1 should no longer be in parent list"
11968         # the new path should appear
11969         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
11970                 error "$FID2/$tfile.moved is not in parent list"
11971
11972         # 6.2) linkea update on unlink
11973         rm -f $DIR/$tdir/d/foo2/link
11974         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
11975         # foo2/link should no longer be returned in parent list
11976         echo "$parent" | grep -F "$FID2/link" &&
11977                 error "$FID2/link should no longer be in parent list"
11978         true
11979
11980         rm -f $DIR/f
11981         restore_lustre_params < $save
11982         rm -f $save
11983 }
11984 run_test 154f "get parent fids by reading link ea"
11985
11986 test_154g()
11987 {
11988         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11989         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
11990            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
11991                 skip "Need MDS version at least 2.6.92"
11992
11993         mkdir -p $DIR/$tdir
11994         llapi_fid_test -d $DIR/$tdir
11995 }
11996 run_test 154g "various llapi FID tests"
11997
11998 test_155_small_load() {
11999     local temp=$TMP/$tfile
12000     local file=$DIR/$tfile
12001
12002     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12003         error "dd of=$temp bs=6096 count=1 failed"
12004     cp $temp $file
12005     cancel_lru_locks $OSC
12006     cmp $temp $file || error "$temp $file differ"
12007
12008     $TRUNCATE $temp 6000
12009     $TRUNCATE $file 6000
12010     cmp $temp $file || error "$temp $file differ (truncate1)"
12011
12012     echo "12345" >>$temp
12013     echo "12345" >>$file
12014     cmp $temp $file || error "$temp $file differ (append1)"
12015
12016     echo "12345" >>$temp
12017     echo "12345" >>$file
12018     cmp $temp $file || error "$temp $file differ (append2)"
12019
12020     rm -f $temp $file
12021     true
12022 }
12023
12024 test_155_big_load() {
12025         remote_ost_nodsh && skip "remote OST with nodsh"
12026
12027         local temp=$TMP/$tfile
12028         local file=$DIR/$tfile
12029
12030         free_min_max
12031         local cache_size=$(do_facet ost$((MAXI+1)) \
12032                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12033         local large_file_size=$((cache_size * 2))
12034
12035         echo "OSS cache size: $cache_size KB"
12036         echo "Large file size: $large_file_size KB"
12037
12038         [ $MAXV -le $large_file_size ] &&
12039                 skip_env "max available OST size needs > $large_file_size KB"
12040
12041         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12042
12043         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12044                 error "dd of=$temp bs=$large_file_size count=1k failed"
12045         cp $temp $file
12046         ls -lh $temp $file
12047         cancel_lru_locks osc
12048         cmp $temp $file || error "$temp $file differ"
12049
12050         rm -f $temp $file
12051         true
12052 }
12053
12054 save_writethrough() {
12055         local facets=$(get_facets OST)
12056
12057         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12058 }
12059
12060 test_155a() {
12061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12062
12063         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12064
12065         save_writethrough $p
12066
12067         set_cache read on
12068         set_cache writethrough on
12069         test_155_small_load
12070         restore_lustre_params < $p
12071         rm -f $p
12072 }
12073 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12074
12075 test_155b() {
12076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12077
12078         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12079
12080         save_writethrough $p
12081
12082         set_cache read on
12083         set_cache writethrough off
12084         test_155_small_load
12085         restore_lustre_params < $p
12086         rm -f $p
12087 }
12088 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12089
12090 test_155c() {
12091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12092
12093         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12094
12095         save_writethrough $p
12096
12097         set_cache read off
12098         set_cache writethrough on
12099         test_155_small_load
12100         restore_lustre_params < $p
12101         rm -f $p
12102 }
12103 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12104
12105 test_155d() {
12106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12107
12108         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12109
12110         save_writethrough $p
12111
12112         set_cache read off
12113         set_cache writethrough off
12114         test_155_small_load
12115         restore_lustre_params < $p
12116         rm -f $p
12117 }
12118 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12119
12120 test_155e() {
12121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12122
12123         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12124
12125         save_writethrough $p
12126
12127         set_cache read on
12128         set_cache writethrough on
12129         test_155_big_load
12130         restore_lustre_params < $p
12131         rm -f $p
12132 }
12133 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12134
12135 test_155f() {
12136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12137
12138         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12139
12140         save_writethrough $p
12141
12142         set_cache read on
12143         set_cache writethrough off
12144         test_155_big_load
12145         restore_lustre_params < $p
12146         rm -f $p
12147 }
12148 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12149
12150 test_155g() {
12151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12152
12153         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12154
12155         save_writethrough $p
12156
12157         set_cache read off
12158         set_cache writethrough on
12159         test_155_big_load
12160         restore_lustre_params < $p
12161         rm -f $p
12162 }
12163 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12164
12165 test_155h() {
12166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12167
12168         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12169
12170         save_writethrough $p
12171
12172         set_cache read off
12173         set_cache writethrough off
12174         test_155_big_load
12175         restore_lustre_params < $p
12176         rm -f $p
12177 }
12178 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12179
12180 test_156() {
12181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12182         remote_ost_nodsh && skip "remote OST with nodsh"
12183         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12184                 skip "stats not implemented on old servers"
12185         [ "$ost1_FSTYPE" = "zfs" ] &&
12186                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12187
12188         local CPAGES=3
12189         local BEFORE
12190         local AFTER
12191         local file="$DIR/$tfile"
12192         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12193
12194         save_writethrough $p
12195         roc_hit_init
12196
12197         log "Turn on read and write cache"
12198         set_cache read on
12199         set_cache writethrough on
12200
12201         log "Write data and read it back."
12202         log "Read should be satisfied from the cache."
12203         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12204         BEFORE=$(roc_hit)
12205         cancel_lru_locks osc
12206         cat $file >/dev/null
12207         AFTER=$(roc_hit)
12208         if ! let "AFTER - BEFORE == CPAGES"; then
12209                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12210         else
12211                 log "cache hits:: before: $BEFORE, after: $AFTER"
12212         fi
12213
12214         log "Read again; it should be satisfied from the cache."
12215         BEFORE=$AFTER
12216         cancel_lru_locks osc
12217         cat $file >/dev/null
12218         AFTER=$(roc_hit)
12219         if ! let "AFTER - BEFORE == CPAGES"; then
12220                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12221         else
12222                 log "cache hits:: before: $BEFORE, after: $AFTER"
12223         fi
12224
12225         log "Turn off the read cache and turn on the write cache"
12226         set_cache read off
12227         set_cache writethrough on
12228
12229         log "Read again; it should be satisfied from the cache."
12230         BEFORE=$(roc_hit)
12231         cancel_lru_locks osc
12232         cat $file >/dev/null
12233         AFTER=$(roc_hit)
12234         if ! let "AFTER - BEFORE == CPAGES"; then
12235                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12236         else
12237                 log "cache hits:: before: $BEFORE, after: $AFTER"
12238         fi
12239
12240         log "Read again; it should not be satisfied from the cache."
12241         BEFORE=$AFTER
12242         cancel_lru_locks osc
12243         cat $file >/dev/null
12244         AFTER=$(roc_hit)
12245         if ! let "AFTER - BEFORE == 0"; then
12246                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12247         else
12248                 log "cache hits:: before: $BEFORE, after: $AFTER"
12249         fi
12250
12251         log "Write data and read it back."
12252         log "Read should be satisfied from the cache."
12253         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12254         BEFORE=$(roc_hit)
12255         cancel_lru_locks osc
12256         cat $file >/dev/null
12257         AFTER=$(roc_hit)
12258         if ! let "AFTER - BEFORE == CPAGES"; then
12259                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12260         else
12261                 log "cache hits:: before: $BEFORE, after: $AFTER"
12262         fi
12263
12264         log "Read again; it should not be satisfied from the cache."
12265         BEFORE=$AFTER
12266         cancel_lru_locks osc
12267         cat $file >/dev/null
12268         AFTER=$(roc_hit)
12269         if ! let "AFTER - BEFORE == 0"; then
12270                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12271         else
12272                 log "cache hits:: before: $BEFORE, after: $AFTER"
12273         fi
12274
12275         log "Turn off read and write cache"
12276         set_cache read off
12277         set_cache writethrough off
12278
12279         log "Write data and read it back"
12280         log "It should not be satisfied from the cache."
12281         rm -f $file
12282         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12283         cancel_lru_locks osc
12284         BEFORE=$(roc_hit)
12285         cat $file >/dev/null
12286         AFTER=$(roc_hit)
12287         if ! let "AFTER - BEFORE == 0"; then
12288                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12289         else
12290                 log "cache hits:: before: $BEFORE, after: $AFTER"
12291         fi
12292
12293         log "Turn on the read cache and turn off the write cache"
12294         set_cache read on
12295         set_cache writethrough off
12296
12297         log "Write data and read it back"
12298         log "It should not be satisfied from the cache."
12299         rm -f $file
12300         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12301         BEFORE=$(roc_hit)
12302         cancel_lru_locks osc
12303         cat $file >/dev/null
12304         AFTER=$(roc_hit)
12305         if ! let "AFTER - BEFORE == 0"; then
12306                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12307         else
12308                 log "cache hits:: before: $BEFORE, after: $AFTER"
12309         fi
12310
12311         log "Read again; it should be satisfied from the cache."
12312         BEFORE=$(roc_hit)
12313         cancel_lru_locks osc
12314         cat $file >/dev/null
12315         AFTER=$(roc_hit)
12316         if ! let "AFTER - BEFORE == CPAGES"; then
12317                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12318         else
12319                 log "cache hits:: before: $BEFORE, after: $AFTER"
12320         fi
12321
12322         restore_lustre_params < $p
12323         rm -f $p $file
12324 }
12325 run_test 156 "Verification of tunables"
12326
12327 test_160a() {
12328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12329         remote_mds_nodsh && skip "remote MDS with nodsh"
12330         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12331                 skip "Need MDS version at least 2.2.0"
12332
12333         changelog_register || error "changelog_register failed"
12334         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12335         changelog_users $SINGLEMDS | grep -q $cl_user ||
12336                 error "User $cl_user not found in changelog_users"
12337
12338         # change something
12339         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12340         changelog_clear 0 || error "changelog_clear failed"
12341         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12342         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12343         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12344         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12345         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12346         rm $DIR/$tdir/pics/desktop.jpg
12347
12348         changelog_dump | tail -10
12349
12350         echo "verifying changelog mask"
12351         changelog_chmask "-MKDIR"
12352         changelog_chmask "-CLOSE"
12353
12354         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12355         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12356
12357         changelog_chmask "+MKDIR"
12358         changelog_chmask "+CLOSE"
12359
12360         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12361         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12362
12363         changelog_dump | tail -10
12364         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12365         CLOSES=$(changelog_dump | grep -c "CLOSE")
12366         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12367         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12368
12369         # verify contents
12370         echo "verifying target fid"
12371         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12372         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12373         [ "$fidc" == "$fidf" ] ||
12374                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12375         echo "verifying parent fid"
12376         # The FID returned from the Changelog may be the directory shard on
12377         # a different MDT, and not the FID returned by path2fid on the parent.
12378         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12379         # since this is what will matter when recreating this file in the tree.
12380         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12381         local pathp=$($LFS fid2path $MOUNT "$fidp")
12382         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12383                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12384
12385         echo "getting records for $cl_user"
12386         changelog_users $SINGLEMDS
12387         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12388         local nclr=3
12389         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12390                 error "changelog_clear failed"
12391         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12392         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12393         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12394                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12395
12396         local min0_rec=$(changelog_users $SINGLEMDS |
12397                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12398         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12399                           awk '{ print $1; exit; }')
12400
12401         changelog_dump | tail -n 5
12402         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12403         [ $first_rec == $((min0_rec + 1)) ] ||
12404                 error "first index should be $min0_rec + 1 not $first_rec"
12405
12406         # LU-3446 changelog index reset on MDT restart
12407         local cur_rec1=$(changelog_users $SINGLEMDS |
12408                          awk '/^current.index:/ { print $NF }')
12409         changelog_clear 0 ||
12410                 error "clear all changelog records for $cl_user failed"
12411         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12412         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12413                 error "Fail to start $SINGLEMDS"
12414         local cur_rec2=$(changelog_users $SINGLEMDS |
12415                          awk '/^current.index:/ { print $NF }')
12416         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12417         [ $cur_rec1 == $cur_rec2 ] ||
12418                 error "current index should be $cur_rec1 not $cur_rec2"
12419
12420         echo "verifying users from this test are deregistered"
12421         changelog_deregister || error "changelog_deregister failed"
12422         changelog_users $SINGLEMDS | grep -q $cl_user &&
12423                 error "User '$cl_user' still in changelog_users"
12424
12425         # lctl get_param -n mdd.*.changelog_users
12426         # current index: 144
12427         # ID    index (idle seconds)
12428         # cl3   144 (2)
12429         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12430                 # this is the normal case where all users were deregistered
12431                 # make sure no new records are added when no users are present
12432                 local last_rec1=$(changelog_users $SINGLEMDS |
12433                                   awk '/^current.index:/ { print $NF }')
12434                 touch $DIR/$tdir/chloe
12435                 local last_rec2=$(changelog_users $SINGLEMDS |
12436                                   awk '/^current.index:/ { print $NF }')
12437                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
12438                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
12439         else
12440                 # any changelog users must be leftovers from a previous test
12441                 changelog_users $SINGLEMDS
12442                 echo "other changelog users; can't verify off"
12443         fi
12444 }
12445 run_test 160a "changelog sanity"
12446
12447 test_160b() { # LU-3587
12448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12449         remote_mds_nodsh && skip "remote MDS with nodsh"
12450         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12451                 skip "Need MDS version at least 2.2.0"
12452
12453         changelog_register || error "changelog_register failed"
12454         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12455         changelog_users $SINGLEMDS | grep -q $cl_user ||
12456                 error "User '$cl_user' not found in changelog_users"
12457
12458         local longname1=$(str_repeat a 255)
12459         local longname2=$(str_repeat b 255)
12460
12461         cd $DIR
12462         echo "creating very long named file"
12463         touch $longname1 || error "create of '$longname1' failed"
12464         echo "renaming very long named file"
12465         mv $longname1 $longname2
12466
12467         changelog_dump | grep RENME | tail -n 5
12468         rm -f $longname2
12469 }
12470 run_test 160b "Verify that very long rename doesn't crash in changelog"
12471
12472 test_160c() {
12473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12474         remote_mds_nodsh && skip "remote MDS with nodsh"
12475
12476         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
12477                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
12478                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
12479                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
12480
12481         local rc=0
12482
12483         # Registration step
12484         changelog_register || error "changelog_register failed"
12485
12486         rm -rf $DIR/$tdir
12487         mkdir -p $DIR/$tdir
12488         $MCREATE $DIR/$tdir/foo_160c
12489         changelog_chmask "-TRUNC"
12490         $TRUNCATE $DIR/$tdir/foo_160c 200
12491         changelog_chmask "+TRUNC"
12492         $TRUNCATE $DIR/$tdir/foo_160c 199
12493         changelog_dump | tail -n 5
12494         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
12495         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
12496 }
12497 run_test 160c "verify that changelog log catch the truncate event"
12498
12499 test_160d() {
12500         remote_mds_nodsh && skip "remote MDS with nodsh"
12501         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12503         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
12504                 skip "Need MDS version at least 2.7.60"
12505
12506         # Registration step
12507         changelog_register || error "changelog_register failed"
12508
12509         mkdir -p $DIR/$tdir/migrate_dir
12510         changelog_clear 0 || error "changelog_clear failed"
12511
12512         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
12513         changelog_dump | tail -n 5
12514         local migrates=$(changelog_dump | grep -c "MIGRT")
12515         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
12516 }
12517 run_test 160d "verify that changelog log catch the migrate event"
12518
12519 test_160e() {
12520         remote_mds_nodsh && skip "remote MDS with nodsh"
12521
12522         # Create a user
12523         changelog_register || error "changelog_register failed"
12524
12525         # Delete a future user (expect fail)
12526         local MDT0=$(facet_svc $SINGLEMDS)
12527         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
12528         local rc=$?
12529
12530         if [ $rc -eq 0 ]; then
12531                 error "Deleted non-existant user cl77"
12532         elif [ $rc -ne 2 ]; then
12533                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
12534         fi
12535
12536         # Clear to a bad index (1 billion should be safe)
12537         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
12538         rc=$?
12539
12540         if [ $rc -eq 0 ]; then
12541                 error "Successfully cleared to invalid CL index"
12542         elif [ $rc -ne 22 ]; then
12543                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
12544         fi
12545 }
12546 run_test 160e "changelog negative testing (should return errors)"
12547
12548 test_160f() {
12549         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12550         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12551                 skip "Need MDS version at least 2.10.56"
12552
12553         local mdts=$(comma_list $(mdts_nodes))
12554
12555         # Create a user
12556         changelog_register || error "first changelog_register failed"
12557         changelog_register || error "second changelog_register failed"
12558         local cl_users
12559         declare -A cl_user1
12560         declare -A cl_user2
12561         local user_rec1
12562         local user_rec2
12563         local i
12564
12565         # generate some changelog records to accumulate on each MDT
12566         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12567         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12568                 error "create $DIR/$tdir/$tfile failed"
12569
12570         # check changelogs have been generated
12571         local nbcl=$(changelog_dump | wc -l)
12572         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12573
12574         for param in "changelog_max_idle_time=10" \
12575                      "changelog_gc=1" \
12576                      "changelog_min_gc_interval=2" \
12577                      "changelog_min_free_cat_entries=3"; do
12578                 local MDT0=$(facet_svc $SINGLEMDS)
12579                 local var="${param%=*}"
12580                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12581
12582                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12583                 do_nodes $mdts $LCTL set_param mdd.*.$param
12584         done
12585
12586         # force cl_user2 to be idle (1st part)
12587         sleep 9
12588
12589         # simulate changelog catalog almost full
12590         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12591         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12592
12593         for i in $(seq $MDSCOUNT); do
12594                 cl_users=(${CL_USERS[mds$i]})
12595                 cl_user1[mds$i]="${cl_users[0]}"
12596                 cl_user2[mds$i]="${cl_users[1]}"
12597
12598                 [ -n "${cl_user1[mds$i]}" ] ||
12599                         error "mds$i: no user registered"
12600                 [ -n "${cl_user2[mds$i]}" ] ||
12601                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12602
12603                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12604                 [ -n "$user_rec1" ] ||
12605                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12606                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12607                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12608                 [ -n "$user_rec2" ] ||
12609                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12610                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12611                      "$user_rec1 + 2 == $user_rec2"
12612                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12613                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12614                               "$user_rec1 + 2, but is $user_rec2"
12615                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12616                 [ -n "$user_rec2" ] ||
12617                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12618                 [ $user_rec1 == $user_rec2 ] ||
12619                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12620                               "$user_rec1, but is $user_rec2"
12621         done
12622
12623         # force cl_user2 to be idle (2nd part) and to reach
12624         # changelog_max_idle_time
12625         sleep 2
12626
12627         # generate one more changelog to trigger fail_loc
12628         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12629                 error "create $DIR/$tdir/${tfile}bis failed"
12630
12631         # ensure gc thread is done
12632         for i in $(mdts_nodes); do
12633                 wait_update $i \
12634                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12635                         error "$i: GC-thread not done"
12636         done
12637
12638         local first_rec
12639         for i in $(seq $MDSCOUNT); do
12640                 # check cl_user1 still registered
12641                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12642                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12643                 # check cl_user2 unregistered
12644                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12645                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12646
12647                 # check changelogs are present and starting at $user_rec1 + 1
12648                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12649                 [ -n "$user_rec1" ] ||
12650                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12651                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12652                             awk '{ print $1; exit; }')
12653
12654                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12655                 [ $((user_rec1 + 1)) == $first_rec ] ||
12656                         error "mds$i: first index should be $user_rec1 + 1, " \
12657                               "but is $first_rec"
12658         done
12659 }
12660 run_test 160f "changelog garbage collect (timestamped users)"
12661
12662 test_160g() {
12663         remote_mds_nodsh && skip "remote MDS with nodsh"
12664         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12665                 skip "Need MDS version at least 2.10.56"
12666
12667         local mdts=$(comma_list $(mdts_nodes))
12668
12669         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
12670         do_nodes $mdts $LCTL set_param fail_loc=0x1314
12671
12672         # Create a user
12673         changelog_register || error "first changelog_register failed"
12674         changelog_register || error "second changelog_register failed"
12675         local cl_users
12676         declare -A cl_user1
12677         declare -A cl_user2
12678         local user_rec1
12679         local user_rec2
12680         local i
12681
12682         # generate some changelog records to accumulate on each MDT
12683         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
12684         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12685                 error "create $DIR/$tdir/$tfile failed"
12686
12687         # check changelogs have been generated
12688         local nbcl=$(changelog_dump | wc -l)
12689         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12690
12691         # reduce the max_idle_indexes value to make sure we exceed it
12692         max_ndx=$((nbcl / 2 - 1))
12693
12694         for param in "changelog_max_idle_indexes=$max_ndx" \
12695                      "changelog_gc=1" \
12696                      "changelog_min_gc_interval=2" \
12697                      "changelog_min_free_cat_entries=3"; do
12698                 local MDT0=$(facet_svc $SINGLEMDS)
12699                 local var="${param%=*}"
12700                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12701
12702                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12703                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
12704                         error "unable to set mdd.*.$param"
12705         done
12706
12707         # simulate changelog catalog almost full
12708         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12709         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12710
12711         for i in $(seq $MDSCOUNT); do
12712                 cl_users=(${CL_USERS[mds$i]})
12713                 cl_user1[mds$i]="${cl_users[0]}"
12714                 cl_user2[mds$i]="${cl_users[1]}"
12715
12716                 [ -n "${cl_user1[mds$i]}" ] ||
12717                         error "mds$i: no user registered"
12718                 [ -n "${cl_user2[mds$i]}" ] ||
12719                         error "mds$i: only ${cl_user1[mds$i]} is registered"
12720
12721                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12722                 [ -n "$user_rec1" ] ||
12723                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12724                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12725                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12726                 [ -n "$user_rec2" ] ||
12727                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12728                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12729                      "$user_rec1 + 2 == $user_rec2"
12730                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12731                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12732                               "$user_rec1 + 2, but is $user_rec2"
12733                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12734                 [ -n "$user_rec2" ] ||
12735                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12736                 [ $user_rec1 == $user_rec2 ] ||
12737                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12738                               "$user_rec1, but is $user_rec2"
12739         done
12740
12741         # ensure we are past the previous changelog_min_gc_interval set above
12742         sleep 2
12743
12744         # generate one more changelog to trigger fail_loc
12745         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12746                 error "create $DIR/$tdir/${tfile}bis failed"
12747
12748         # ensure gc thread is done
12749         for i in $(mdts_nodes); do
12750                 wait_update $i \
12751                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12752                         error "$i: GC-thread not done"
12753         done
12754
12755         local first_rec
12756         for i in $(seq $MDSCOUNT); do
12757                 # check cl_user1 still registered
12758                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12759                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12760                 # check cl_user2 unregistered
12761                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12762                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12763
12764                 # check changelogs are present and starting at $user_rec1 + 1
12765                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12766                 [ -n "$user_rec1" ] ||
12767                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12768                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12769                             awk '{ print $1; exit; }')
12770
12771                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12772                 [ $((user_rec1 + 1)) == $first_rec ] ||
12773                         error "mds$i: first index should be $user_rec1 + 1, " \
12774                               "but is $first_rec"
12775         done
12776 }
12777 run_test 160g "changelog garbage collect (old users)"
12778
12779 test_160h() {
12780         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12781         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12782                 skip "Need MDS version at least 2.10.56"
12783
12784         local mdts=$(comma_list $(mdts_nodes))
12785
12786         # Create a user
12787         changelog_register || error "first changelog_register failed"
12788         changelog_register || error "second changelog_register failed"
12789         local cl_users
12790         declare -A cl_user1
12791         declare -A cl_user2
12792         local user_rec1
12793         local user_rec2
12794         local i
12795
12796         # generate some changelog records to accumulate on each MDT
12797         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12798         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12799                 error "create $DIR/$tdir/$tfile failed"
12800
12801         # check changelogs have been generated
12802         local nbcl=$(changelog_dump | wc -l)
12803         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12804
12805         for param in "changelog_max_idle_time=10" \
12806                      "changelog_gc=1" \
12807                      "changelog_min_gc_interval=2"; do
12808                 local MDT0=$(facet_svc $SINGLEMDS)
12809                 local var="${param%=*}"
12810                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12811
12812                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12813                 do_nodes $mdts $LCTL set_param mdd.*.$param
12814         done
12815
12816         # force cl_user2 to be idle (1st part)
12817         sleep 9
12818
12819         for i in $(seq $MDSCOUNT); do
12820                 cl_users=(${CL_USERS[mds$i]})
12821                 cl_user1[mds$i]="${cl_users[0]}"
12822                 cl_user2[mds$i]="${cl_users[1]}"
12823
12824                 [ -n "${cl_user1[mds$i]}" ] ||
12825                         error "mds$i: no user registered"
12826                 [ -n "${cl_user2[mds$i]}" ] ||
12827                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12828
12829                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12830                 [ -n "$user_rec1" ] ||
12831                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12832                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12833                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12834                 [ -n "$user_rec2" ] ||
12835                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12836                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12837                      "$user_rec1 + 2 == $user_rec2"
12838                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12839                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12840                               "$user_rec1 + 2, but is $user_rec2"
12841                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12842                 [ -n "$user_rec2" ] ||
12843                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12844                 [ $user_rec1 == $user_rec2 ] ||
12845                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12846                               "$user_rec1, but is $user_rec2"
12847         done
12848
12849         # force cl_user2 to be idle (2nd part) and to reach
12850         # changelog_max_idle_time
12851         sleep 2
12852
12853         # force each GC-thread start and block then
12854         # one per MDT/MDD, set fail_val accordingly
12855         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
12856         do_nodes $mdts $LCTL set_param fail_loc=0x1316
12857
12858         # generate more changelogs to trigger fail_loc
12859         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12860                 error "create $DIR/$tdir/${tfile}bis failed"
12861
12862         # stop MDT to stop GC-thread, should be done in back-ground as it will
12863         # block waiting for the thread to be released and exit
12864         declare -A stop_pids
12865         for i in $(seq $MDSCOUNT); do
12866                 stop mds$i &
12867                 stop_pids[mds$i]=$!
12868         done
12869
12870         for i in $(mdts_nodes); do
12871                 local facet
12872                 local nb=0
12873                 local facets=$(facets_up_on_host $i)
12874
12875                 for facet in ${facets//,/ }; do
12876                         if [[ $facet == mds* ]]; then
12877                                 nb=$((nb + 1))
12878                         fi
12879                 done
12880                 # ensure each MDS's gc threads are still present and all in "R"
12881                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
12882                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
12883                         error "$i: expected $nb GC-thread"
12884                 wait_update $i \
12885                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
12886                         "R" 20 ||
12887                         error "$i: GC-thread not found in R-state"
12888                 # check umounts of each MDT on MDS have reached kthread_stop()
12889                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
12890                         error "$i: expected $nb umount"
12891                 wait_update $i \
12892                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
12893                         error "$i: umount not found in D-state"
12894         done
12895
12896         # release all GC-threads
12897         do_nodes $mdts $LCTL set_param fail_loc=0
12898
12899         # wait for MDT stop to complete
12900         for i in $(seq $MDSCOUNT); do
12901                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
12902         done
12903
12904         # XXX
12905         # may try to check if any orphan changelog records are present
12906         # via ldiskfs/zfs and llog_reader...
12907
12908         # re-start/mount MDTs
12909         for i in $(seq $MDSCOUNT); do
12910                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
12911                         error "Fail to start mds$i"
12912         done
12913
12914         local first_rec
12915         for i in $(seq $MDSCOUNT); do
12916                 # check cl_user1 still registered
12917                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12918                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12919                 # check cl_user2 unregistered
12920                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12921                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12922
12923                 # check changelogs are present and starting at $user_rec1 + 1
12924                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12925                 [ -n "$user_rec1" ] ||
12926                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12927                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12928                             awk '{ print $1; exit; }')
12929
12930                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12931                 [ $((user_rec1 + 1)) == $first_rec ] ||
12932                         error "mds$i: first index should be $user_rec1 + 1, " \
12933                               "but is $first_rec"
12934         done
12935 }
12936 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
12937               "during mount"
12938
12939 test_160i() {
12940
12941         local mdts=$(comma_list $(mdts_nodes))
12942
12943         changelog_register || error "first changelog_register failed"
12944
12945         # generate some changelog records to accumulate on each MDT
12946         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
12947         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12948                 error "create $DIR/$tdir/$tfile failed"
12949
12950         # check changelogs have been generated
12951         local nbcl=$(changelog_dump | wc -l)
12952         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12953
12954         # simulate race between register and unregister
12955         # XXX as fail_loc is set per-MDS, with DNE configs the race
12956         # simulation will only occur for one MDT per MDS and for the
12957         # others the normal race scenario will take place
12958         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
12959         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
12960         do_nodes $mdts $LCTL set_param fail_val=1
12961
12962         # unregister 1st user
12963         changelog_deregister &
12964         local pid1=$!
12965         # wait some time for deregister work to reach race rdv
12966         sleep 2
12967         # register 2nd user
12968         changelog_register || error "2nd user register failed"
12969
12970         wait $pid1 || error "1st user deregister failed"
12971
12972         local i
12973         local last_rec
12974         declare -A LAST_REC
12975         for i in $(seq $MDSCOUNT); do
12976                 if changelog_users mds$i | grep "^cl"; then
12977                         # make sure new records are added with one user present
12978                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
12979                                           awk '/^current.index:/ { print $NF }')
12980                 else
12981                         error "mds$i has no user registered"
12982                 fi
12983         done
12984
12985         # generate more changelog records to accumulate on each MDT
12986         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12987                 error "create $DIR/$tdir/${tfile}bis failed"
12988
12989         for i in $(seq $MDSCOUNT); do
12990                 last_rec=$(changelog_users $SINGLEMDS |
12991                            awk '/^current.index:/ { print $NF }')
12992                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
12993                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
12994                         error "changelogs are off on mds$i"
12995         done
12996 }
12997 run_test 160i "changelog user register/unregister race"
12998
12999 test_161a() {
13000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13001
13002         test_mkdir -c1 $DIR/$tdir
13003         cp /etc/hosts $DIR/$tdir/$tfile
13004         test_mkdir -c1 $DIR/$tdir/foo1
13005         test_mkdir -c1 $DIR/$tdir/foo2
13006         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13007         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13008         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13009         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13010         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13011         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13012                 $LFS fid2path $DIR $FID
13013                 error "bad link ea"
13014         fi
13015         # middle
13016         rm $DIR/$tdir/foo2/zachary
13017         # last
13018         rm $DIR/$tdir/foo2/thor
13019         # first
13020         rm $DIR/$tdir/$tfile
13021         # rename
13022         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13023         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13024                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13025         rm $DIR/$tdir/foo2/maggie
13026
13027         # overflow the EA
13028         local longname=$tfile.avg_len_is_thirty_two_
13029         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13030                 error_noexit 'failed to unlink many hardlinks'" EXIT
13031         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13032                 error "failed to hardlink many files"
13033         links=$($LFS fid2path $DIR $FID | wc -l)
13034         echo -n "${links}/1000 links in link EA"
13035         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13036 }
13037 run_test 161a "link ea sanity"
13038
13039 test_161b() {
13040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13041         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13042
13043         local MDTIDX=1
13044         local remote_dir=$DIR/$tdir/remote_dir
13045
13046         mkdir -p $DIR/$tdir
13047         $LFS mkdir -i $MDTIDX $remote_dir ||
13048                 error "create remote directory failed"
13049
13050         cp /etc/hosts $remote_dir/$tfile
13051         mkdir -p $remote_dir/foo1
13052         mkdir -p $remote_dir/foo2
13053         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13054         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13055         ln $remote_dir/$tfile $remote_dir/foo1/luna
13056         ln $remote_dir/$tfile $remote_dir/foo2/thor
13057
13058         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13059                      tr -d ']')
13060         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13061                 $LFS fid2path $DIR $FID
13062                 error "bad link ea"
13063         fi
13064         # middle
13065         rm $remote_dir/foo2/zachary
13066         # last
13067         rm $remote_dir/foo2/thor
13068         # first
13069         rm $remote_dir/$tfile
13070         # rename
13071         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13072         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13073         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13074                 $LFS fid2path $DIR $FID
13075                 error "bad link rename"
13076         fi
13077         rm $remote_dir/foo2/maggie
13078
13079         # overflow the EA
13080         local longname=filename_avg_len_is_thirty_two_
13081         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13082                 error "failed to hardlink many files"
13083         links=$($LFS fid2path $DIR $FID | wc -l)
13084         echo -n "${links}/1000 links in link EA"
13085         [[ ${links} -gt 60 ]] ||
13086                 error "expected at least 60 links in link EA"
13087         unlinkmany $remote_dir/foo2/$longname 1000 ||
13088         error "failed to unlink many hardlinks"
13089 }
13090 run_test 161b "link ea sanity under remote directory"
13091
13092 test_161c() {
13093         remote_mds_nodsh && skip "remote MDS with nodsh"
13094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13095         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13096                 skip "Need MDS version at least 2.1.5"
13097
13098         # define CLF_RENAME_LAST 0x0001
13099         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13100         changelog_register || error "changelog_register failed"
13101
13102         rm -rf $DIR/$tdir
13103         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13104         touch $DIR/$tdir/foo_161c
13105         touch $DIR/$tdir/bar_161c
13106         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13107         changelog_dump | grep RENME | tail -n 5
13108         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13109         changelog_clear 0 || error "changelog_clear failed"
13110         if [ x$flags != "x0x1" ]; then
13111                 error "flag $flags is not 0x1"
13112         fi
13113
13114         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13115         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13116         touch $DIR/$tdir/foo_161c
13117         touch $DIR/$tdir/bar_161c
13118         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13119         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13120         changelog_dump | grep RENME | tail -n 5
13121         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13122         changelog_clear 0 || error "changelog_clear failed"
13123         if [ x$flags != "x0x0" ]; then
13124                 error "flag $flags is not 0x0"
13125         fi
13126         echo "rename overwrite a target having nlink > 1," \
13127                 "changelog record has flags of $flags"
13128
13129         # rename doesn't overwrite a target (changelog flag 0x0)
13130         touch $DIR/$tdir/foo_161c
13131         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13132         changelog_dump | grep RENME | tail -n 5
13133         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13134         changelog_clear 0 || error "changelog_clear failed"
13135         if [ x$flags != "x0x0" ]; then
13136                 error "flag $flags is not 0x0"
13137         fi
13138         echo "rename doesn't overwrite a target," \
13139                 "changelog record has flags of $flags"
13140
13141         # define CLF_UNLINK_LAST 0x0001
13142         # unlink a file having nlink = 1 (changelog flag 0x1)
13143         rm -f $DIR/$tdir/foo2_161c
13144         changelog_dump | grep UNLNK | tail -n 5
13145         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13146         changelog_clear 0 || error "changelog_clear failed"
13147         if [ x$flags != "x0x1" ]; then
13148                 error "flag $flags is not 0x1"
13149         fi
13150         echo "unlink a file having nlink = 1," \
13151                 "changelog record has flags of $flags"
13152
13153         # unlink a file having nlink > 1 (changelog flag 0x0)
13154         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13155         rm -f $DIR/$tdir/foobar_161c
13156         changelog_dump | grep UNLNK | tail -n 5
13157         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13158         changelog_clear 0 || error "changelog_clear failed"
13159         if [ x$flags != "x0x0" ]; then
13160                 error "flag $flags is not 0x0"
13161         fi
13162         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13163 }
13164 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13165
13166 test_161d() {
13167         remote_mds_nodsh && skip "remote MDS with nodsh"
13168         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13169
13170         local pid
13171         local fid
13172
13173         changelog_register || error "changelog_register failed"
13174
13175         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13176         # interfer with $MOUNT/.lustre/fid/ access
13177         mkdir $DIR/$tdir
13178         [[ $? -eq 0 ]] || error "mkdir failed"
13179
13180         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13181         $LCTL set_param fail_loc=0x8000140c
13182         # 5s pause
13183         $LCTL set_param fail_val=5
13184
13185         # create file
13186         echo foofoo > $DIR/$tdir/$tfile &
13187         pid=$!
13188
13189         # wait for create to be delayed
13190         sleep 2
13191
13192         ps -p $pid
13193         [[ $? -eq 0 ]] || error "create should be blocked"
13194
13195         local tempfile=$(mktemp)
13196         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13197         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13198         # some delay may occur during ChangeLog publishing and file read just
13199         # above, that could allow file write to happen finally
13200         [[ -s $tempfile ]] && echo "file should be empty"
13201
13202         $LCTL set_param fail_loc=0
13203
13204         wait $pid
13205         [[ $? -eq 0 ]] || error "create failed"
13206 }
13207 run_test 161d "create with concurrent .lustre/fid access"
13208
13209 check_path() {
13210         local expected="$1"
13211         shift
13212         local fid="$2"
13213
13214         local path
13215         path=$($LFS fid2path "$@")
13216         local rc=$?
13217
13218         if [ $rc -ne 0 ]; then
13219                 error "path looked up of '$expected' failed: rc=$rc"
13220         elif [ "$path" != "$expected" ]; then
13221                 error "path looked up '$path' instead of '$expected'"
13222         else
13223                 echo "FID '$fid' resolves to path '$path' as expected"
13224         fi
13225 }
13226
13227 test_162a() { # was test_162
13228         test_mkdir -p -c1 $DIR/$tdir/d2
13229         touch $DIR/$tdir/d2/$tfile
13230         touch $DIR/$tdir/d2/x1
13231         touch $DIR/$tdir/d2/x2
13232         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13233         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13234         # regular file
13235         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13236         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13237
13238         # softlink
13239         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13240         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13241         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13242
13243         # softlink to wrong file
13244         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13245         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13246         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13247
13248         # hardlink
13249         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13250         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13251         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13252         # fid2path dir/fsname should both work
13253         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13254         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13255
13256         # hardlink count: check that there are 2 links
13257         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13258         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13259
13260         # hardlink indexing: remove the first link
13261         rm $DIR/$tdir/d2/p/q/r/hlink
13262         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13263 }
13264 run_test 162a "path lookup sanity"
13265
13266 test_162b() {
13267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13268         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13269
13270         mkdir $DIR/$tdir
13271         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13272                                 error "create striped dir failed"
13273
13274         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13275                                         tail -n 1 | awk '{print $2}')
13276         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13277
13278         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13279         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13280
13281         # regular file
13282         for ((i=0;i<5;i++)); do
13283                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13284                         error "get fid for f$i failed"
13285                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13286
13287                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13288                         error "get fid for d$i failed"
13289                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13290         done
13291
13292         return 0
13293 }
13294 run_test 162b "striped directory path lookup sanity"
13295
13296 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13297 test_162c() {
13298         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13299                 skip "Need MDS version at least 2.7.51"
13300
13301         local lpath=$tdir.local
13302         local rpath=$tdir.remote
13303
13304         test_mkdir $DIR/$lpath
13305         test_mkdir $DIR/$rpath
13306
13307         for ((i = 0; i <= 101; i++)); do
13308                 lpath="$lpath/$i"
13309                 mkdir $DIR/$lpath
13310                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13311                         error "get fid for local directory $DIR/$lpath failed"
13312                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13313
13314                 rpath="$rpath/$i"
13315                 test_mkdir $DIR/$rpath
13316                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13317                         error "get fid for remote directory $DIR/$rpath failed"
13318                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13319         done
13320
13321         return 0
13322 }
13323 run_test 162c "fid2path works with paths 100 or more directories deep"
13324
13325 test_169() {
13326         # do directio so as not to populate the page cache
13327         log "creating a 10 Mb file"
13328         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13329         log "starting reads"
13330         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13331         log "truncating the file"
13332         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13333         log "killing dd"
13334         kill %+ || true # reads might have finished
13335         echo "wait until dd is finished"
13336         wait
13337         log "removing the temporary file"
13338         rm -rf $DIR/$tfile || error "tmp file removal failed"
13339 }
13340 run_test 169 "parallel read and truncate should not deadlock"
13341
13342 test_170() {
13343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13344
13345         $LCTL clear     # bug 18514
13346         $LCTL debug_daemon start $TMP/${tfile}_log_good
13347         touch $DIR/$tfile
13348         $LCTL debug_daemon stop
13349         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13350                 error "sed failed to read log_good"
13351
13352         $LCTL debug_daemon start $TMP/${tfile}_log_good
13353         rm -rf $DIR/$tfile
13354         $LCTL debug_daemon stop
13355
13356         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13357                error "lctl df log_bad failed"
13358
13359         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13360         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13361
13362         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13363         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13364
13365         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13366                 error "bad_line good_line1 good_line2 are empty"
13367
13368         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13369         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13370         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13371
13372         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13373         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13374         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13375
13376         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13377                 error "bad_line_new good_line_new are empty"
13378
13379         local expected_good=$((good_line1 + good_line2*2))
13380
13381         rm -f $TMP/${tfile}*
13382         # LU-231, short malformed line may not be counted into bad lines
13383         if [ $bad_line -ne $bad_line_new ] &&
13384                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13385                 error "expected $bad_line bad lines, but got $bad_line_new"
13386                 return 1
13387         fi
13388
13389         if [ $expected_good -ne $good_line_new ]; then
13390                 error "expected $expected_good good lines, but got $good_line_new"
13391                 return 2
13392         fi
13393         true
13394 }
13395 run_test 170 "test lctl df to handle corrupted log ====================="
13396
13397 test_171() { # bug20592
13398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13399
13400         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13401         $LCTL set_param fail_loc=0x50e
13402         $LCTL set_param fail_val=3000
13403         multiop_bg_pause $DIR/$tfile O_s || true
13404         local MULTIPID=$!
13405         kill -USR1 $MULTIPID
13406         # cause log dump
13407         sleep 3
13408         wait $MULTIPID
13409         if dmesg | grep "recursive fault"; then
13410                 error "caught a recursive fault"
13411         fi
13412         $LCTL set_param fail_loc=0
13413         true
13414 }
13415 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13416
13417 # it would be good to share it with obdfilter-survey/iokit-libecho code
13418 setup_obdecho_osc () {
13419         local rc=0
13420         local ost_nid=$1
13421         local obdfilter_name=$2
13422         echo "Creating new osc for $obdfilter_name on $ost_nid"
13423         # make sure we can find loopback nid
13424         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13425
13426         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13427                            ${obdfilter_name}_osc_UUID || rc=2; }
13428         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13429                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13430         return $rc
13431 }
13432
13433 cleanup_obdecho_osc () {
13434         local obdfilter_name=$1
13435         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
13436         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
13437         return 0
13438 }
13439
13440 obdecho_test() {
13441         local OBD=$1
13442         local node=$2
13443         local pages=${3:-64}
13444         local rc=0
13445         local id
13446
13447         local count=10
13448         local obd_size=$(get_obd_size $node $OBD)
13449         local page_size=$(get_page_size $node)
13450         if [[ -n "$obd_size" ]]; then
13451                 local new_count=$((obd_size / (pages * page_size / 1024)))
13452                 [[ $new_count -ge $count ]] || count=$new_count
13453         fi
13454
13455         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
13456         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
13457                            rc=2; }
13458         if [ $rc -eq 0 ]; then
13459             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
13460             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
13461         fi
13462         echo "New object id is $id"
13463         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
13464                            rc=4; }
13465         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
13466                            "test_brw $count w v $pages $id" || rc=4; }
13467         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
13468                            rc=4; }
13469         [ $rc -eq 0 -o $rc -gt 2 ] && { do_facet $node "$LCTL --device ec "    \
13470                                         "cleanup" || rc=5; }
13471         [ $rc -eq 0 -o $rc -gt 1 ] && { do_facet $node "$LCTL --device ec "    \
13472                                         "detach" || rc=6; }
13473         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
13474         return $rc
13475 }
13476
13477 test_180a() {
13478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13479
13480         if ! module_loaded obdecho; then
13481                 load_module obdecho/obdecho &&
13482                         stack_trap "rmmod obdecho" EXIT ||
13483                         error "unable to load obdecho on client"
13484         fi
13485
13486         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
13487         local host=$($LCTL get_param -n osc.$osc.import |
13488                      awk '/current_connection:/ { print $2 }' )
13489         local target=$($LCTL get_param -n osc.$osc.import |
13490                        awk '/target:/ { print $2 }' )
13491         target=${target%_UUID}
13492
13493         if [ -n "$target" ]; then
13494                 setup_obdecho_osc $host $target &&
13495                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
13496                         { error "obdecho setup failed with $?"; return; }
13497
13498                 obdecho_test ${target}_osc client ||
13499                         error "obdecho_test failed on ${target}_osc"
13500         else
13501                 $LCTL get_param osc.$osc.import
13502                 error "there is no osc.$osc.import target"
13503         fi
13504 }
13505 run_test 180a "test obdecho on osc"
13506
13507 test_180b() {
13508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13509         remote_ost_nodsh && skip "remote OST with nodsh"
13510
13511         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13512                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13513                 error "failed to load module obdecho"
13514
13515         local target=$(do_facet ost1 $LCTL dl |
13516                        awk '/obdfilter/ { print $4; exit; }')
13517
13518         if [ -n "$target" ]; then
13519                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
13520         else
13521                 do_facet ost1 $LCTL dl
13522                 error "there is no obdfilter target on ost1"
13523         fi
13524 }
13525 run_test 180b "test obdecho directly on obdfilter"
13526
13527 test_180c() { # LU-2598
13528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13529         remote_ost_nodsh && skip "remote OST with nodsh"
13530         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
13531                 skip "Need MDS version at least 2.4.0"
13532
13533         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13534                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13535                 error "failed to load module obdecho"
13536
13537         local target=$(do_facet ost1 $LCTL dl |
13538                        awk '/obdfilter/ { print $4; exit; }')
13539
13540         if [ -n "$target" ]; then
13541                 local pages=16384 # 64MB bulk I/O RPC size
13542
13543                 obdecho_test "$target" ost1 "$pages" ||
13544                         error "obdecho_test with pages=$pages failed with $?"
13545         else
13546                 do_facet ost1 $LCTL dl
13547                 error "there is no obdfilter target on ost1"
13548         fi
13549 }
13550 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
13551
13552 test_181() { # bug 22177
13553         test_mkdir $DIR/$tdir
13554         # create enough files to index the directory
13555         createmany -o $DIR/$tdir/foobar 4000
13556         # print attributes for debug purpose
13557         lsattr -d .
13558         # open dir
13559         multiop_bg_pause $DIR/$tdir D_Sc || return 1
13560         MULTIPID=$!
13561         # remove the files & current working dir
13562         unlinkmany $DIR/$tdir/foobar 4000
13563         rmdir $DIR/$tdir
13564         kill -USR1 $MULTIPID
13565         wait $MULTIPID
13566         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
13567         return 0
13568 }
13569 run_test 181 "Test open-unlinked dir ========================"
13570
13571 test_182() {
13572         local fcount=1000
13573         local tcount=10
13574
13575         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13576
13577         $LCTL set_param mdc.*.rpc_stats=clear
13578
13579         for (( i = 0; i < $tcount; i++ )) ; do
13580                 mkdir $DIR/$tdir/$i
13581         done
13582
13583         for (( i = 0; i < $tcount; i++ )) ; do
13584                 createmany -o $DIR/$tdir/$i/f- $fcount &
13585         done
13586         wait
13587
13588         for (( i = 0; i < $tcount; i++ )) ; do
13589                 unlinkmany $DIR/$tdir/$i/f- $fcount &
13590         done
13591         wait
13592
13593         $LCTL get_param mdc.*.rpc_stats
13594
13595         rm -rf $DIR/$tdir
13596 }
13597 run_test 182 "Test parallel modify metadata operations ================"
13598
13599 test_183() { # LU-2275
13600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13601         remote_mds_nodsh && skip "remote MDS with nodsh"
13602         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
13603                 skip "Need MDS version at least 2.3.56"
13604
13605         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13606         echo aaa > $DIR/$tdir/$tfile
13607
13608 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
13609         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
13610
13611         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
13612         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
13613
13614         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
13615
13616         # Flush negative dentry cache
13617         touch $DIR/$tdir/$tfile
13618
13619         # We are not checking for any leaked references here, they'll
13620         # become evident next time we do cleanup with module unload.
13621         rm -rf $DIR/$tdir
13622 }
13623 run_test 183 "No crash or request leak in case of strange dispositions ========"
13624
13625 # test suite 184 is for LU-2016, LU-2017
13626 test_184a() {
13627         check_swap_layouts_support
13628
13629         dir0=$DIR/$tdir/$testnum
13630         test_mkdir -p -c1 $dir0
13631         ref1=/etc/passwd
13632         ref2=/etc/group
13633         file1=$dir0/f1
13634         file2=$dir0/f2
13635         $LFS setstripe -c1 $file1
13636         cp $ref1 $file1
13637         $LFS setstripe -c2 $file2
13638         cp $ref2 $file2
13639         gen1=$($LFS getstripe -g $file1)
13640         gen2=$($LFS getstripe -g $file2)
13641
13642         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
13643         gen=$($LFS getstripe -g $file1)
13644         [[ $gen1 != $gen ]] ||
13645                 "Layout generation on $file1 does not change"
13646         gen=$($LFS getstripe -g $file2)
13647         [[ $gen2 != $gen ]] ||
13648                 "Layout generation on $file2 does not change"
13649
13650         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
13651         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
13652
13653         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
13654 }
13655 run_test 184a "Basic layout swap"
13656
13657 test_184b() {
13658         check_swap_layouts_support
13659
13660         dir0=$DIR/$tdir/$testnum
13661         mkdir -p $dir0 || error "creating dir $dir0"
13662         file1=$dir0/f1
13663         file2=$dir0/f2
13664         file3=$dir0/f3
13665         dir1=$dir0/d1
13666         dir2=$dir0/d2
13667         mkdir $dir1 $dir2
13668         $LFS setstripe -c1 $file1
13669         $LFS setstripe -c2 $file2
13670         $LFS setstripe -c1 $file3
13671         chown $RUNAS_ID $file3
13672         gen1=$($LFS getstripe -g $file1)
13673         gen2=$($LFS getstripe -g $file2)
13674
13675         $LFS swap_layouts $dir1 $dir2 &&
13676                 error "swap of directories layouts should fail"
13677         $LFS swap_layouts $dir1 $file1 &&
13678                 error "swap of directory and file layouts should fail"
13679         $RUNAS $LFS swap_layouts $file1 $file2 &&
13680                 error "swap of file we cannot write should fail"
13681         $LFS swap_layouts $file1 $file3 &&
13682                 error "swap of file with different owner should fail"
13683         /bin/true # to clear error code
13684 }
13685 run_test 184b "Forbidden layout swap (will generate errors)"
13686
13687 test_184c() {
13688         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
13689         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
13690         check_swap_layouts_support
13691
13692         local dir0=$DIR/$tdir/$testnum
13693         mkdir -p $dir0 || error "creating dir $dir0"
13694
13695         local ref1=$dir0/ref1
13696         local ref2=$dir0/ref2
13697         local file1=$dir0/file1
13698         local file2=$dir0/file2
13699         # create a file large enough for the concurrent test
13700         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
13701         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
13702         echo "ref file size: ref1($(stat -c %s $ref1))," \
13703              "ref2($(stat -c %s $ref2))"
13704
13705         cp $ref2 $file2
13706         dd if=$ref1 of=$file1 bs=16k &
13707         local DD_PID=$!
13708
13709         # Make sure dd starts to copy file
13710         while [ ! -f $file1 ]; do sleep 0.1; done
13711
13712         $LFS swap_layouts $file1 $file2
13713         local rc=$?
13714         wait $DD_PID
13715         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
13716         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
13717
13718         # how many bytes copied before swapping layout
13719         local copied=$(stat -c %s $file2)
13720         local remaining=$(stat -c %s $ref1)
13721         remaining=$((remaining - copied))
13722         echo "Copied $copied bytes before swapping layout..."
13723
13724         cmp -n $copied $file1 $ref2 | grep differ &&
13725                 error "Content mismatch [0, $copied) of ref2 and file1"
13726         cmp -n $copied $file2 $ref1 ||
13727                 error "Content mismatch [0, $copied) of ref1 and file2"
13728         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
13729                 error "Content mismatch [$copied, EOF) of ref1 and file1"
13730
13731         # clean up
13732         rm -f $ref1 $ref2 $file1 $file2
13733 }
13734 run_test 184c "Concurrent write and layout swap"
13735
13736 test_184d() {
13737         check_swap_layouts_support
13738         [ -z "$(which getfattr 2>/dev/null)" ] &&
13739                 skip_env "no getfattr command"
13740
13741         local file1=$DIR/$tdir/$tfile-1
13742         local file2=$DIR/$tdir/$tfile-2
13743         local file3=$DIR/$tdir/$tfile-3
13744         local lovea1
13745         local lovea2
13746
13747         mkdir -p $DIR/$tdir
13748         touch $file1 || error "create $file1 failed"
13749         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13750                 error "create $file2 failed"
13751         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13752                 error "create $file3 failed"
13753         lovea1=$(get_layout_param $file1)
13754
13755         $LFS swap_layouts $file2 $file3 ||
13756                 error "swap $file2 $file3 layouts failed"
13757         $LFS swap_layouts $file1 $file2 ||
13758                 error "swap $file1 $file2 layouts failed"
13759
13760         lovea2=$(get_layout_param $file2)
13761         echo "$lovea1"
13762         echo "$lovea2"
13763         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
13764
13765         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13766         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
13767 }
13768 run_test 184d "allow stripeless layouts swap"
13769
13770 test_184e() {
13771         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
13772                 skip "Need MDS version at least 2.6.94"
13773         check_swap_layouts_support
13774         [ -z "$(which getfattr 2>/dev/null)" ] &&
13775                 skip_env "no getfattr command"
13776
13777         local file1=$DIR/$tdir/$tfile-1
13778         local file2=$DIR/$tdir/$tfile-2
13779         local file3=$DIR/$tdir/$tfile-3
13780         local lovea
13781
13782         mkdir -p $DIR/$tdir
13783         touch $file1 || error "create $file1 failed"
13784         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13785                 error "create $file2 failed"
13786         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13787                 error "create $file3 failed"
13788
13789         $LFS swap_layouts $file1 $file2 ||
13790                 error "swap $file1 $file2 layouts failed"
13791
13792         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13793         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
13794
13795         echo 123 > $file1 || error "Should be able to write into $file1"
13796
13797         $LFS swap_layouts $file1 $file3 ||
13798                 error "swap $file1 $file3 layouts failed"
13799
13800         echo 123 > $file1 || error "Should be able to write into $file1"
13801
13802         rm -rf $file1 $file2 $file3
13803 }
13804 run_test 184e "Recreate layout after stripeless layout swaps"
13805
13806 test_184f() {
13807         # Create a file with name longer than sizeof(struct stat) ==
13808         # 144 to see if we can get chars from the file name to appear
13809         # in the returned striping. Note that 'f' == 0x66.
13810         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
13811
13812         mkdir -p $DIR/$tdir
13813         mcreate $DIR/$tdir/$file
13814         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
13815                 error "IOC_MDC_GETFILEINFO returned garbage striping"
13816         fi
13817 }
13818 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
13819
13820 test_185() { # LU-2441
13821         # LU-3553 - no volatile file support in old servers
13822         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
13823                 skip "Need MDS version at least 2.3.60"
13824
13825         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13826         touch $DIR/$tdir/spoo
13827         local mtime1=$(stat -c "%Y" $DIR/$tdir)
13828         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
13829                 error "cannot create/write a volatile file"
13830         [ "$FILESET" == "" ] &&
13831         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
13832                 error "FID is still valid after close"
13833
13834         multiop_bg_pause $DIR/$tdir vVw4096_c
13835         local multi_pid=$!
13836
13837         local OLD_IFS=$IFS
13838         IFS=":"
13839         local fidv=($fid)
13840         IFS=$OLD_IFS
13841         # assume that the next FID for this client is sequential, since stdout
13842         # is unfortunately eaten by multiop_bg_pause
13843         local n=$((${fidv[1]} + 1))
13844         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
13845         if [ "$FILESET" == "" ]; then
13846                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
13847                         error "FID is missing before close"
13848         fi
13849         kill -USR1 $multi_pid
13850         # 1 second delay, so if mtime change we will see it
13851         sleep 1
13852         local mtime2=$(stat -c "%Y" $DIR/$tdir)
13853         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
13854 }
13855 run_test 185 "Volatile file support"
13856
13857 test_187a() {
13858         remote_mds_nodsh && skip "remote MDS with nodsh"
13859         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13860                 skip "Need MDS version at least 2.3.0"
13861
13862         local dir0=$DIR/$tdir/$testnum
13863         mkdir -p $dir0 || error "creating dir $dir0"
13864
13865         local file=$dir0/file1
13866         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
13867         local dv1=$($LFS data_version $file)
13868         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
13869         local dv2=$($LFS data_version $file)
13870         [[ $dv1 != $dv2 ]] ||
13871                 error "data version did not change on write $dv1 == $dv2"
13872
13873         # clean up
13874         rm -f $file1
13875 }
13876 run_test 187a "Test data version change"
13877
13878 test_187b() {
13879         remote_mds_nodsh && skip "remote MDS with nodsh"
13880         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13881                 skip "Need MDS version at least 2.3.0"
13882
13883         local dir0=$DIR/$tdir/$testnum
13884         mkdir -p $dir0 || error "creating dir $dir0"
13885
13886         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
13887         [[ ${DV[0]} != ${DV[1]} ]] ||
13888                 error "data version did not change on write"\
13889                       " ${DV[0]} == ${DV[1]}"
13890
13891         # clean up
13892         rm -f $file1
13893 }
13894 run_test 187b "Test data version change on volatile file"
13895
13896 test_200() {
13897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13898         remote_mgs_nodsh && skip "remote MGS with nodsh"
13899         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13900
13901         local POOL=${POOL:-cea1}
13902         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
13903         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
13904         # Pool OST targets
13905         local first_ost=0
13906         local last_ost=$(($OSTCOUNT - 1))
13907         local ost_step=2
13908         local ost_list=$(seq $first_ost $ost_step $last_ost)
13909         local ost_range="$first_ost $last_ost $ost_step"
13910         local test_path=$POOL_ROOT/$POOL_DIR_NAME
13911         local file_dir=$POOL_ROOT/file_tst
13912         local subdir=$test_path/subdir
13913         local rc=0
13914
13915         if ! combined_mgs_mds ; then
13916                 mount_mgs_client
13917         fi
13918
13919         while : ; do
13920                 # former test_200a test_200b
13921                 pool_add $POOL                          || { rc=$? ; break; }
13922                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
13923                 # former test_200c test_200d
13924                 mkdir -p $test_path
13925                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
13926                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
13927                 mkdir -p $subdir
13928                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
13929                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
13930                                                         || { rc=$? ; break; }
13931                 # former test_200e test_200f
13932                 local files=$((OSTCOUNT*3))
13933                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
13934                                                         || { rc=$? ; break; }
13935                 pool_create_files $POOL $file_dir $files "$ost_list" \
13936                                                         || { rc=$? ; break; }
13937                 # former test_200g test_200h
13938                 pool_lfs_df $POOL                       || { rc=$? ; break; }
13939                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
13940
13941                 # former test_201a test_201b test_201c
13942                 pool_remove_first_target $POOL          || { rc=$? ; break; }
13943
13944                 local f=$test_path/$tfile
13945                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
13946                 pool_remove $POOL $f                    || { rc=$? ; break; }
13947                 break
13948         done
13949
13950         destroy_test_pools
13951
13952         if ! combined_mgs_mds ; then
13953                 umount_mgs_client
13954         fi
13955         return $rc
13956 }
13957 run_test 200 "OST pools"
13958
13959 # usage: default_attr <count | size | offset>
13960 default_attr() {
13961         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
13962 }
13963
13964 # usage: check_default_stripe_attr
13965 check_default_stripe_attr() {
13966         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
13967         case $1 in
13968         --stripe-count|-c)
13969                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
13970         --stripe-size|-S)
13971                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
13972         --stripe-index|-i)
13973                 EXPECTED=-1;;
13974         *)
13975                 error "unknown getstripe attr '$1'"
13976         esac
13977
13978         [ $ACTUAL == $EXPECTED ] ||
13979                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
13980 }
13981
13982 test_204a() {
13983         test_mkdir $DIR/$tdir
13984         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
13985
13986         check_default_stripe_attr --stripe-count
13987         check_default_stripe_attr --stripe-size
13988         check_default_stripe_attr --stripe-index
13989 }
13990 run_test 204a "Print default stripe attributes"
13991
13992 test_204b() {
13993         test_mkdir $DIR/$tdir
13994         $LFS setstripe --stripe-count 1 $DIR/$tdir
13995
13996         check_default_stripe_attr --stripe-size
13997         check_default_stripe_attr --stripe-index
13998 }
13999 run_test 204b "Print default stripe size and offset"
14000
14001 test_204c() {
14002         test_mkdir $DIR/$tdir
14003         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14004
14005         check_default_stripe_attr --stripe-count
14006         check_default_stripe_attr --stripe-index
14007 }
14008 run_test 204c "Print default stripe count and offset"
14009
14010 test_204d() {
14011         test_mkdir $DIR/$tdir
14012         $LFS setstripe --stripe-index 0 $DIR/$tdir
14013
14014         check_default_stripe_attr --stripe-count
14015         check_default_stripe_attr --stripe-size
14016 }
14017 run_test 204d "Print default stripe count and size"
14018
14019 test_204e() {
14020         test_mkdir $DIR/$tdir
14021         $LFS setstripe -d $DIR/$tdir
14022
14023         check_default_stripe_attr --stripe-count --raw
14024         check_default_stripe_attr --stripe-size --raw
14025         check_default_stripe_attr --stripe-index --raw
14026 }
14027 run_test 204e "Print raw stripe attributes"
14028
14029 test_204f() {
14030         test_mkdir $DIR/$tdir
14031         $LFS setstripe --stripe-count 1 $DIR/$tdir
14032
14033         check_default_stripe_attr --stripe-size --raw
14034         check_default_stripe_attr --stripe-index --raw
14035 }
14036 run_test 204f "Print raw stripe size and offset"
14037
14038 test_204g() {
14039         test_mkdir $DIR/$tdir
14040         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14041
14042         check_default_stripe_attr --stripe-count --raw
14043         check_default_stripe_attr --stripe-index --raw
14044 }
14045 run_test 204g "Print raw stripe count and offset"
14046
14047 test_204h() {
14048         test_mkdir $DIR/$tdir
14049         $LFS setstripe --stripe-index 0 $DIR/$tdir
14050
14051         check_default_stripe_attr --stripe-count --raw
14052         check_default_stripe_attr --stripe-size --raw
14053 }
14054 run_test 204h "Print raw stripe count and size"
14055
14056 # Figure out which job scheduler is being used, if any,
14057 # or use a fake one
14058 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14059         JOBENV=SLURM_JOB_ID
14060 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14061         JOBENV=LSB_JOBID
14062 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14063         JOBENV=PBS_JOBID
14064 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14065         JOBENV=LOADL_STEP_ID
14066 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14067         JOBENV=JOB_ID
14068 else
14069         $LCTL list_param jobid_name > /dev/null 2>&1
14070         if [ $? -eq 0 ]; then
14071                 JOBENV=nodelocal
14072         else
14073                 JOBENV=FAKE_JOBID
14074         fi
14075 fi
14076 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14077
14078 verify_jobstats() {
14079         local cmd=($1)
14080         shift
14081         local facets="$@"
14082
14083 # we don't really need to clear the stats for this test to work, since each
14084 # command has a unique jobid, but it makes debugging easier if needed.
14085 #       for facet in $facets; do
14086 #               local dev=$(convert_facet2label $facet)
14087 #               # clear old jobstats
14088 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14089 #       done
14090
14091         # use a new JobID for each test, or we might see an old one
14092         [ "$JOBENV" = "FAKE_JOBID" ] &&
14093                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14094
14095         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14096
14097         [ "$JOBENV" = "nodelocal" ] && {
14098                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14099                 $LCTL set_param jobid_name=$FAKE_JOBID
14100                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14101         }
14102
14103         log "Test: ${cmd[*]}"
14104         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14105
14106         if [ $JOBENV = "FAKE_JOBID" ]; then
14107                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14108         else
14109                 ${cmd[*]}
14110         fi
14111
14112         # all files are created on OST0000
14113         for facet in $facets; do
14114                 local stats="*.$(convert_facet2label $facet).job_stats"
14115
14116                 # strip out libtool wrappers for in-tree executables
14117                 if [ $(do_facet $facet lctl get_param $stats |
14118                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14119                         do_facet $facet lctl get_param $stats
14120                         error "No jobstats for $JOBVAL found on $facet::$stats"
14121                 fi
14122         done
14123 }
14124
14125 jobstats_set() {
14126         local new_jobenv=$1
14127
14128         set_persistent_param_and_check client "jobid_var" \
14129                 "$FSNAME.sys.jobid_var" $new_jobenv
14130 }
14131
14132 test_205() { # Job stats
14133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14134         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14135                 skip "Need MDS version with at least 2.7.1"
14136         remote_mgs_nodsh && skip "remote MGS with nodsh"
14137         remote_mds_nodsh && skip "remote MDS with nodsh"
14138         remote_ost_nodsh && skip "remote OST with nodsh"
14139         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14140                 skip "Server doesn't support jobstats"
14141         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14142
14143         local old_jobenv=$($LCTL get_param -n jobid_var)
14144         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14145
14146         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14147                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14148         else
14149                 stack_trap "do_facet mgs $PERM_CMD \
14150                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14151         fi
14152         changelog_register
14153
14154         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14155                                 mdt.*.job_cleanup_interval | head -n 1)
14156         local new_interval=5
14157         do_facet $SINGLEMDS \
14158                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14159         stack_trap "do_facet $SINGLEMDS \
14160                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14161         local start=$SECONDS
14162
14163         local cmd
14164         # mkdir
14165         cmd="mkdir $DIR/$tdir"
14166         verify_jobstats "$cmd" "$SINGLEMDS"
14167         # rmdir
14168         cmd="rmdir $DIR/$tdir"
14169         verify_jobstats "$cmd" "$SINGLEMDS"
14170         # mkdir on secondary MDT
14171         if [ $MDSCOUNT -gt 1 ]; then
14172                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14173                 verify_jobstats "$cmd" "mds2"
14174         fi
14175         # mknod
14176         cmd="mknod $DIR/$tfile c 1 3"
14177         verify_jobstats "$cmd" "$SINGLEMDS"
14178         # unlink
14179         cmd="rm -f $DIR/$tfile"
14180         verify_jobstats "$cmd" "$SINGLEMDS"
14181         # create all files on OST0000 so verify_jobstats can find OST stats
14182         # open & close
14183         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14184         verify_jobstats "$cmd" "$SINGLEMDS"
14185         # setattr
14186         cmd="touch $DIR/$tfile"
14187         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14188         # write
14189         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14190         verify_jobstats "$cmd" "ost1"
14191         # read
14192         cancel_lru_locks osc
14193         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14194         verify_jobstats "$cmd" "ost1"
14195         # truncate
14196         cmd="$TRUNCATE $DIR/$tfile 0"
14197         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14198         # rename
14199         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14200         verify_jobstats "$cmd" "$SINGLEMDS"
14201         # jobstats expiry - sleep until old stats should be expired
14202         local left=$((new_interval + 5 - (SECONDS - start)))
14203         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14204                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14205                         "0" $left
14206         cmd="mkdir $DIR/$tdir.expire"
14207         verify_jobstats "$cmd" "$SINGLEMDS"
14208         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14209             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14210
14211         # Ensure that jobid are present in changelog (if supported by MDS)
14212         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14213                 changelog_dump | tail -10
14214                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14215                 [ $jobids -eq 9 ] ||
14216                         error "Wrong changelog jobid count $jobids != 9"
14217
14218                 # LU-5862
14219                 JOBENV="disable"
14220                 jobstats_set $JOBENV
14221                 touch $DIR/$tfile
14222                 changelog_dump | grep $tfile
14223                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14224                 [ $jobids -eq 0 ] ||
14225                         error "Unexpected jobids when jobid_var=$JOBENV"
14226         fi
14227
14228         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14229         JOBENV="JOBCOMPLEX"
14230         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14231
14232         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14233 }
14234 run_test 205 "Verify job stats"
14235
14236 # LU-1480, LU-1773 and LU-1657
14237 test_206() {
14238         mkdir -p $DIR/$tdir
14239         $LFS setstripe -c -1 $DIR/$tdir
14240 #define OBD_FAIL_LOV_INIT 0x1403
14241         $LCTL set_param fail_loc=0xa0001403
14242         $LCTL set_param fail_val=1
14243         touch $DIR/$tdir/$tfile || true
14244 }
14245 run_test 206 "fail lov_init_raid0() doesn't lbug"
14246
14247 test_207a() {
14248         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14249         local fsz=`stat -c %s $DIR/$tfile`
14250         cancel_lru_locks mdc
14251
14252         # do not return layout in getattr intent
14253 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14254         $LCTL set_param fail_loc=0x170
14255         local sz=`stat -c %s $DIR/$tfile`
14256
14257         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14258
14259         rm -rf $DIR/$tfile
14260 }
14261 run_test 207a "can refresh layout at glimpse"
14262
14263 test_207b() {
14264         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14265         local cksum=`md5sum $DIR/$tfile`
14266         local fsz=`stat -c %s $DIR/$tfile`
14267         cancel_lru_locks mdc
14268         cancel_lru_locks osc
14269
14270         # do not return layout in getattr intent
14271 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14272         $LCTL set_param fail_loc=0x171
14273
14274         # it will refresh layout after the file is opened but before read issues
14275         echo checksum is "$cksum"
14276         echo "$cksum" |md5sum -c --quiet || error "file differs"
14277
14278         rm -rf $DIR/$tfile
14279 }
14280 run_test 207b "can refresh layout at open"
14281
14282 test_208() {
14283         # FIXME: in this test suite, only RD lease is used. This is okay
14284         # for now as only exclusive open is supported. After generic lease
14285         # is done, this test suite should be revised. - Jinshan
14286
14287         remote_mds_nodsh && skip "remote MDS with nodsh"
14288         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14289                 skip "Need MDS version at least 2.4.52"
14290
14291         echo "==== test 1: verify get lease work"
14292         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14293
14294         echo "==== test 2: verify lease can be broken by upcoming open"
14295         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14296         local PID=$!
14297         sleep 1
14298
14299         $MULTIOP $DIR/$tfile oO_RDONLY:c
14300         kill -USR1 $PID && wait $PID || error "break lease error"
14301
14302         echo "==== test 3: verify lease can't be granted if an open already exists"
14303         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14304         local PID=$!
14305         sleep 1
14306
14307         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14308         kill -USR1 $PID && wait $PID || error "open file error"
14309
14310         echo "==== test 4: lease can sustain over recovery"
14311         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14312         PID=$!
14313         sleep 1
14314
14315         fail mds1
14316
14317         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14318
14319         echo "==== test 5: lease broken can't be regained by replay"
14320         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14321         PID=$!
14322         sleep 1
14323
14324         # open file to break lease and then recovery
14325         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14326         fail mds1
14327
14328         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14329
14330         rm -f $DIR/$tfile
14331 }
14332 run_test 208 "Exclusive open"
14333
14334 test_209() {
14335         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14336                 skip_env "must have disp_stripe"
14337
14338         touch $DIR/$tfile
14339         sync; sleep 5; sync;
14340
14341         echo 3 > /proc/sys/vm/drop_caches
14342         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14343
14344         # open/close 500 times
14345         for i in $(seq 500); do
14346                 cat $DIR/$tfile
14347         done
14348
14349         echo 3 > /proc/sys/vm/drop_caches
14350         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14351
14352         echo "before: $req_before, after: $req_after"
14353         [ $((req_after - req_before)) -ge 300 ] &&
14354                 error "open/close requests are not freed"
14355         return 0
14356 }
14357 run_test 209 "read-only open/close requests should be freed promptly"
14358
14359 test_212() {
14360         size=`date +%s`
14361         size=$((size % 8192 + 1))
14362         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14363         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14364         rm -f $DIR/f212 $DIR/f212.xyz
14365 }
14366 run_test 212 "Sendfile test ============================================"
14367
14368 test_213() {
14369         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14370         cancel_lru_locks osc
14371         lctl set_param fail_loc=0x8000040f
14372         # generate a read lock
14373         cat $DIR/$tfile > /dev/null
14374         # write to the file, it will try to cancel the above read lock.
14375         cat /etc/hosts >> $DIR/$tfile
14376 }
14377 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14378
14379 test_214() { # for bug 20133
14380         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14381         for (( i=0; i < 340; i++ )) ; do
14382                 touch $DIR/$tdir/d214c/a$i
14383         done
14384
14385         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14386         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14387         ls $DIR/d214c || error "ls $DIR/d214c failed"
14388         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14389         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14390 }
14391 run_test 214 "hash-indexed directory test - bug 20133"
14392
14393 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14394 create_lnet_proc_files() {
14395         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14396 }
14397
14398 # counterpart of create_lnet_proc_files
14399 remove_lnet_proc_files() {
14400         rm -f $TMP/lnet_$1.sys
14401 }
14402
14403 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14404 # 3rd arg as regexp for body
14405 check_lnet_proc_stats() {
14406         local l=$(cat "$TMP/lnet_$1" |wc -l)
14407         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14408
14409         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14410 }
14411
14412 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14413 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14414 # optional and can be regexp for 2nd line (lnet.routes case)
14415 check_lnet_proc_entry() {
14416         local blp=2          # blp stands for 'position of 1st line of body'
14417         [ -z "$5" ] || blp=3 # lnet.routes case
14418
14419         local l=$(cat "$TMP/lnet_$1" |wc -l)
14420         # subtracting one from $blp because the body can be empty
14421         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14422
14423         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14424                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14425
14426         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14427                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14428
14429         # bail out if any unexpected line happened
14430         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
14431         [ "$?" != 0 ] || error "$2 misformatted"
14432 }
14433
14434 test_215() { # for bugs 18102, 21079, 21517
14435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14436
14437         local N='(0|[1-9][0-9]*)'       # non-negative numeric
14438         local P='[1-9][0-9]*'           # positive numeric
14439         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
14440         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
14441         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
14442         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
14443
14444         local L1 # regexp for 1st line
14445         local L2 # regexp for 2nd line (optional)
14446         local BR # regexp for the rest (body)
14447
14448         # lnet.stats should look as 11 space-separated non-negative numerics
14449         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
14450         create_lnet_proc_files "stats"
14451         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
14452         remove_lnet_proc_files "stats"
14453
14454         # lnet.routes should look like this:
14455         # Routing disabled/enabled
14456         # net hops priority state router
14457         # where net is a string like tcp0, hops > 0, priority >= 0,
14458         # state is up/down,
14459         # router is a string like 192.168.1.1@tcp2
14460         L1="^Routing (disabled|enabled)$"
14461         L2="^net +hops +priority +state +router$"
14462         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
14463         create_lnet_proc_files "routes"
14464         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
14465         remove_lnet_proc_files "routes"
14466
14467         # lnet.routers should look like this:
14468         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
14469         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
14470         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
14471         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
14472         L1="^ref +rtr_ref +alive_cnt +state +last_ping +ping_sent +deadline +down_ni +router$"
14473         BR="^$P +$P +$N +(up|down) +$N +(0|1) +$I +$I +$NID$"
14474         create_lnet_proc_files "routers"
14475         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
14476         remove_lnet_proc_files "routers"
14477
14478         # lnet.peers should look like this:
14479         # nid refs state last max rtr min tx min queue
14480         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
14481         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
14482         # numeric (0 or >0 or <0), queue >= 0.
14483         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
14484         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
14485         create_lnet_proc_files "peers"
14486         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
14487         remove_lnet_proc_files "peers"
14488
14489         # lnet.buffers  should look like this:
14490         # pages count credits min
14491         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
14492         L1="^pages +count +credits +min$"
14493         BR="^ +$N +$N +$I +$I$"
14494         create_lnet_proc_files "buffers"
14495         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
14496         remove_lnet_proc_files "buffers"
14497
14498         # lnet.nis should look like this:
14499         # nid status alive refs peer rtr max tx min
14500         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
14501         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
14502         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
14503         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
14504         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
14505         create_lnet_proc_files "nis"
14506         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
14507         remove_lnet_proc_files "nis"
14508
14509         # can we successfully write to lnet.stats?
14510         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
14511 }
14512 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
14513
14514 test_216() { # bug 20317
14515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14516         remote_ost_nodsh && skip "remote OST with nodsh"
14517
14518         local node
14519         local facets=$(get_facets OST)
14520         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14521
14522         save_lustre_params client "osc.*.contention_seconds" > $p
14523         save_lustre_params $facets \
14524                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
14525         save_lustre_params $facets \
14526                 "ldlm.namespaces.filter-*.contended_locks" >> $p
14527         save_lustre_params $facets \
14528                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
14529         clear_stats osc.*.osc_stats
14530
14531         # agressive lockless i/o settings
14532         do_nodes $(comma_list $(osts_nodes)) \
14533                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
14534                         ldlm.namespaces.filter-*.contended_locks=0 \
14535                         ldlm.namespaces.filter-*.contention_seconds=60"
14536         lctl set_param -n osc.*.contention_seconds=60
14537
14538         $DIRECTIO write $DIR/$tfile 0 10 4096
14539         $CHECKSTAT -s 40960 $DIR/$tfile
14540
14541         # disable lockless i/o
14542         do_nodes $(comma_list $(osts_nodes)) \
14543                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
14544                         ldlm.namespaces.filter-*.contended_locks=32 \
14545                         ldlm.namespaces.filter-*.contention_seconds=0"
14546         lctl set_param -n osc.*.contention_seconds=0
14547         clear_stats osc.*.osc_stats
14548
14549         dd if=/dev/zero of=$DIR/$tfile count=0
14550         $CHECKSTAT -s 0 $DIR/$tfile
14551
14552         restore_lustre_params <$p
14553         rm -f $p
14554         rm $DIR/$tfile
14555 }
14556 run_test 216 "check lockless direct write updates file size and kms correctly"
14557
14558 test_217() { # bug 22430
14559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14560
14561         local node
14562         local nid
14563
14564         for node in $(nodes_list); do
14565                 nid=$(host_nids_address $node $NETTYPE)
14566                 if [[ $nid = *-* ]] ; then
14567                         echo "lctl ping $(h2nettype $nid)"
14568                         lctl ping $(h2nettype $nid)
14569                 else
14570                         echo "skipping $node (no hyphen detected)"
14571                 fi
14572         done
14573 }
14574 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
14575
14576 test_218() {
14577        # do directio so as not to populate the page cache
14578        log "creating a 10 Mb file"
14579        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14580        log "starting reads"
14581        dd if=$DIR/$tfile of=/dev/null bs=4096 &
14582        log "truncating the file"
14583        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14584        log "killing dd"
14585        kill %+ || true # reads might have finished
14586        echo "wait until dd is finished"
14587        wait
14588        log "removing the temporary file"
14589        rm -rf $DIR/$tfile || error "tmp file removal failed"
14590 }
14591 run_test 218 "parallel read and truncate should not deadlock"
14592
14593 test_219() {
14594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14595
14596         # write one partial page
14597         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
14598         # set no grant so vvp_io_commit_write will do sync write
14599         $LCTL set_param fail_loc=0x411
14600         # write a full page at the end of file
14601         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
14602
14603         $LCTL set_param fail_loc=0
14604         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
14605         $LCTL set_param fail_loc=0x411
14606         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
14607
14608         # LU-4201
14609         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
14610         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
14611 }
14612 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
14613
14614 test_220() { #LU-325
14615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14616         remote_ost_nodsh && skip "remote OST with nodsh"
14617         remote_mds_nodsh && skip "remote MDS with nodsh"
14618         remote_mgs_nodsh && skip "remote MGS with nodsh"
14619
14620         local OSTIDX=0
14621
14622         # create on MDT0000 so the last_id and next_id are correct
14623         mkdir $DIR/$tdir
14624         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
14625         OST=${OST%_UUID}
14626
14627         # on the mdt's osc
14628         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
14629         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
14630                         osc.$mdtosc_proc1.prealloc_last_id)
14631         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
14632                         osc.$mdtosc_proc1.prealloc_next_id)
14633
14634         $LFS df -i
14635
14636         if ! combined_mgs_mds ; then
14637                 mount_mgs_client
14638         fi
14639
14640         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
14641         #define OBD_FAIL_OST_ENOINO              0x229
14642         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
14643         create_pool $FSNAME.$TESTNAME || return 1
14644         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
14645
14646         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
14647
14648         MDSOBJS=$((last_id - next_id))
14649         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
14650
14651         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
14652         echo "OST still has $count kbytes free"
14653
14654         echo "create $MDSOBJS files @next_id..."
14655         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
14656
14657         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14658                         osc.$mdtosc_proc1.prealloc_last_id)
14659         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14660                         osc.$mdtosc_proc1.prealloc_next_id)
14661
14662         echo "after creation, last_id=$last_id2, next_id=$next_id2"
14663         $LFS df -i
14664
14665         echo "cleanup..."
14666
14667         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
14668         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
14669
14670         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
14671                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
14672         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
14673                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
14674         echo "unlink $MDSOBJS files @$next_id..."
14675         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
14676
14677         if ! combined_mgs_mds ; then
14678                 umount_mgs_client
14679         fi
14680 }
14681 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
14682
14683 test_221() {
14684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14685
14686         dd if=`which date` of=$MOUNT/date oflag=sync
14687         chmod +x $MOUNT/date
14688
14689         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
14690         $LCTL set_param fail_loc=0x80001401
14691
14692         $MOUNT/date > /dev/null
14693         rm -f $MOUNT/date
14694 }
14695 run_test 221 "make sure fault and truncate race to not cause OOM"
14696
14697 test_222a () {
14698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14699
14700         rm -rf $DIR/$tdir
14701         test_mkdir $DIR/$tdir
14702         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14703         createmany -o $DIR/$tdir/$tfile 10
14704         cancel_lru_locks mdc
14705         cancel_lru_locks osc
14706         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14707         $LCTL set_param fail_loc=0x31a
14708         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
14709         $LCTL set_param fail_loc=0
14710         rm -r $DIR/$tdir
14711 }
14712 run_test 222a "AGL for ls should not trigger CLIO lock failure"
14713
14714 test_222b () {
14715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14716
14717         rm -rf $DIR/$tdir
14718         test_mkdir $DIR/$tdir
14719         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14720         createmany -o $DIR/$tdir/$tfile 10
14721         cancel_lru_locks mdc
14722         cancel_lru_locks osc
14723         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14724         $LCTL set_param fail_loc=0x31a
14725         rm -r $DIR/$tdir || error "AGL for rmdir failed"
14726         $LCTL set_param fail_loc=0
14727 }
14728 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
14729
14730 test_223 () {
14731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14732
14733         rm -rf $DIR/$tdir
14734         test_mkdir $DIR/$tdir
14735         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14736         createmany -o $DIR/$tdir/$tfile 10
14737         cancel_lru_locks mdc
14738         cancel_lru_locks osc
14739         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
14740         $LCTL set_param fail_loc=0x31b
14741         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
14742         $LCTL set_param fail_loc=0
14743         rm -r $DIR/$tdir
14744 }
14745 run_test 223 "osc reenqueue if without AGL lock granted ======================="
14746
14747 test_224a() { # LU-1039, MRP-303
14748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14749
14750         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
14751         $LCTL set_param fail_loc=0x508
14752         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
14753         $LCTL set_param fail_loc=0
14754         df $DIR
14755 }
14756 run_test 224a "Don't panic on bulk IO failure"
14757
14758 test_224b() { # LU-1039, MRP-303
14759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14760
14761         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
14762         cancel_lru_locks osc
14763         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
14764         $LCTL set_param fail_loc=0x515
14765         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
14766         $LCTL set_param fail_loc=0
14767         df $DIR
14768 }
14769 run_test 224b "Don't panic on bulk IO failure"
14770
14771 test_224c() { # LU-6441
14772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14773         remote_mds_nodsh && skip "remote MDS with nodsh"
14774
14775         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14776         save_writethrough $p
14777         set_cache writethrough on
14778
14779         local pages_per_rpc=$($LCTL get_param \
14780                                 osc.*.max_pages_per_rpc)
14781         local at_max=$($LCTL get_param -n at_max)
14782         local timeout=$($LCTL get_param -n timeout)
14783         local test_at="at_max"
14784         local param_at="$FSNAME.sys.at_max"
14785         local test_timeout="timeout"
14786         local param_timeout="$FSNAME.sys.timeout"
14787
14788         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
14789
14790         set_persistent_param_and_check client "$test_at" "$param_at" 0
14791         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
14792
14793         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
14794         do_facet ost1 "$LCTL set_param fail_loc=0x520"
14795         $LFS setstripe -c 1 -i 0 $DIR/$tfile
14796         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
14797         sync
14798         do_facet ost1 "$LCTL set_param fail_loc=0"
14799
14800         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
14801         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
14802                 $timeout
14803
14804         $LCTL set_param -n $pages_per_rpc
14805         restore_lustre_params < $p
14806         rm -f $p
14807 }
14808 run_test 224c "Don't hang if one of md lost during large bulk RPC"
14809
14810 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
14811 test_225a () {
14812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14813         if [ -z ${MDSSURVEY} ]; then
14814                 skip_env "mds-survey not found"
14815         fi
14816         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14817                 skip "Need MDS version at least 2.2.51"
14818
14819         local mds=$(facet_host $SINGLEMDS)
14820         local target=$(do_nodes $mds 'lctl dl' |
14821                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14822
14823         local cmd1="file_count=1000 thrhi=4"
14824         local cmd2="dir_count=2 layer=mdd stripe_count=0"
14825         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14826         local cmd="$cmd1 $cmd2 $cmd3"
14827
14828         rm -f ${TMP}/mds_survey*
14829         echo + $cmd
14830         eval $cmd || error "mds-survey with zero-stripe failed"
14831         cat ${TMP}/mds_survey*
14832         rm -f ${TMP}/mds_survey*
14833 }
14834 run_test 225a "Metadata survey sanity with zero-stripe"
14835
14836 test_225b () {
14837         if [ -z ${MDSSURVEY} ]; then
14838                 skip_env "mds-survey not found"
14839         fi
14840         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14841                 skip "Need MDS version at least 2.2.51"
14842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14843         remote_mds_nodsh && skip "remote MDS with nodsh"
14844         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
14845                 skip_env "Need to mount OST to test"
14846         fi
14847
14848         local mds=$(facet_host $SINGLEMDS)
14849         local target=$(do_nodes $mds 'lctl dl' |
14850                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14851
14852         local cmd1="file_count=1000 thrhi=4"
14853         local cmd2="dir_count=2 layer=mdd stripe_count=1"
14854         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14855         local cmd="$cmd1 $cmd2 $cmd3"
14856
14857         rm -f ${TMP}/mds_survey*
14858         echo + $cmd
14859         eval $cmd || error "mds-survey with stripe_count failed"
14860         cat ${TMP}/mds_survey*
14861         rm -f ${TMP}/mds_survey*
14862 }
14863 run_test 225b "Metadata survey sanity with stripe_count = 1"
14864
14865 mcreate_path2fid () {
14866         local mode=$1
14867         local major=$2
14868         local minor=$3
14869         local name=$4
14870         local desc=$5
14871         local path=$DIR/$tdir/$name
14872         local fid
14873         local rc
14874         local fid_path
14875
14876         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
14877                 error "cannot create $desc"
14878
14879         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
14880         rc=$?
14881         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
14882
14883         fid_path=$($LFS fid2path $MOUNT $fid)
14884         rc=$?
14885         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
14886
14887         [ "$path" == "$fid_path" ] ||
14888                 error "fid2path returned $fid_path, expected $path"
14889
14890         echo "pass with $path and $fid"
14891 }
14892
14893 test_226a () {
14894         rm -rf $DIR/$tdir
14895         mkdir -p $DIR/$tdir
14896
14897         mcreate_path2fid 0010666 0 0 fifo "FIFO"
14898         mcreate_path2fid 0020666 1 3 null "character special file (null)"
14899         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
14900         mcreate_path2fid 0040666 0 0 dir "directory"
14901         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
14902         mcreate_path2fid 0100666 0 0 file "regular file"
14903         mcreate_path2fid 0120666 0 0 link "symbolic link"
14904         mcreate_path2fid 0140666 0 0 sock "socket"
14905 }
14906 run_test 226a "call path2fid and fid2path on files of all type"
14907
14908 test_226b () {
14909         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14910
14911         local MDTIDX=1
14912
14913         rm -rf $DIR/$tdir
14914         mkdir -p $DIR/$tdir
14915         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
14916                 error "create remote directory failed"
14917         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
14918         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
14919                                 "character special file (null)"
14920         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
14921                                 "character special file (no device)"
14922         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
14923         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
14924                                 "block special file (loop)"
14925         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
14926         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
14927         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
14928 }
14929 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
14930
14931 # LU-1299 Executing or running ldd on a truncated executable does not
14932 # cause an out-of-memory condition.
14933 test_227() {
14934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14935         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
14936
14937         dd if=$(which date) of=$MOUNT/date bs=1k count=1
14938         chmod +x $MOUNT/date
14939
14940         $MOUNT/date > /dev/null
14941         ldd $MOUNT/date > /dev/null
14942         rm -f $MOUNT/date
14943 }
14944 run_test 227 "running truncated executable does not cause OOM"
14945
14946 # LU-1512 try to reuse idle OI blocks
14947 test_228a() {
14948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14949         remote_mds_nodsh && skip "remote MDS with nodsh"
14950         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
14951
14952         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
14953         local myDIR=$DIR/$tdir
14954
14955         mkdir -p $myDIR
14956         #define OBD_FAIL_SEQ_EXHAUST             0x1002
14957         $LCTL set_param fail_loc=0x80001002
14958         createmany -o $myDIR/t- 10000
14959         $LCTL set_param fail_loc=0
14960         # The guard is current the largest FID holder
14961         touch $myDIR/guard
14962         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
14963                     tr -d '[')
14964         local IDX=$(($SEQ % 64))
14965
14966         do_facet $SINGLEMDS sync
14967         # Make sure journal flushed.
14968         sleep 6
14969         local blk1=$(do_facet $SINGLEMDS \
14970                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
14971                      grep Blockcount | awk '{print $4}')
14972
14973         # Remove old files, some OI blocks will become idle.
14974         unlinkmany $myDIR/t- 10000
14975         # Create new files, idle OI blocks should be reused.
14976         createmany -o $myDIR/t- 2000
14977         do_facet $SINGLEMDS sync
14978         # Make sure journal flushed.
14979         sleep 6
14980         local blk2=$(do_facet $SINGLEMDS \
14981                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
14982                      grep Blockcount | awk '{print $4}')
14983
14984         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
14985 }
14986 run_test 228a "try to reuse idle OI blocks"
14987
14988 test_228b() {
14989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14990         remote_mds_nodsh && skip "remote MDS with nodsh"
14991         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
14992
14993         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
14994         local myDIR=$DIR/$tdir
14995
14996         mkdir -p $myDIR
14997         #define OBD_FAIL_SEQ_EXHAUST             0x1002
14998         $LCTL set_param fail_loc=0x80001002
14999         createmany -o $myDIR/t- 10000
15000         $LCTL set_param fail_loc=0
15001         # The guard is current the largest FID holder
15002         touch $myDIR/guard
15003         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15004                     tr -d '[')
15005         local IDX=$(($SEQ % 64))
15006
15007         do_facet $SINGLEMDS sync
15008         # Make sure journal flushed.
15009         sleep 6
15010         local blk1=$(do_facet $SINGLEMDS \
15011                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15012                      grep Blockcount | awk '{print $4}')
15013
15014         # Remove old files, some OI blocks will become idle.
15015         unlinkmany $myDIR/t- 10000
15016
15017         # stop the MDT
15018         stop $SINGLEMDS || error "Fail to stop MDT."
15019         # remount the MDT
15020         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15021
15022         df $MOUNT || error "Fail to df."
15023         # Create new files, idle OI blocks should be reused.
15024         createmany -o $myDIR/t- 2000
15025         do_facet $SINGLEMDS sync
15026         # Make sure journal flushed.
15027         sleep 6
15028         local blk2=$(do_facet $SINGLEMDS \
15029                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15030                      grep Blockcount | awk '{print $4}')
15031
15032         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15033 }
15034 run_test 228b "idle OI blocks can be reused after MDT restart"
15035
15036 #LU-1881
15037 test_228c() {
15038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15039         remote_mds_nodsh && skip "remote MDS with nodsh"
15040         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15041
15042         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15043         local myDIR=$DIR/$tdir
15044
15045         mkdir -p $myDIR
15046         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15047         $LCTL set_param fail_loc=0x80001002
15048         # 20000 files can guarantee there are index nodes in the OI file
15049         createmany -o $myDIR/t- 20000
15050         $LCTL set_param fail_loc=0
15051         # The guard is current the largest FID holder
15052         touch $myDIR/guard
15053         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15054                     tr -d '[')
15055         local IDX=$(($SEQ % 64))
15056
15057         do_facet $SINGLEMDS sync
15058         # Make sure journal flushed.
15059         sleep 6
15060         local blk1=$(do_facet $SINGLEMDS \
15061                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15062                      grep Blockcount | awk '{print $4}')
15063
15064         # Remove old files, some OI blocks will become idle.
15065         unlinkmany $myDIR/t- 20000
15066         rm -f $myDIR/guard
15067         # The OI file should become empty now
15068
15069         # Create new files, idle OI blocks should be reused.
15070         createmany -o $myDIR/t- 2000
15071         do_facet $SINGLEMDS sync
15072         # Make sure journal flushed.
15073         sleep 6
15074         local blk2=$(do_facet $SINGLEMDS \
15075                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15076                      grep Blockcount | awk '{print $4}')
15077
15078         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15079 }
15080 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15081
15082 test_229() { # LU-2482, LU-3448
15083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15084         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15085         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15086                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15087
15088         rm -f $DIR/$tfile
15089
15090         # Create a file with a released layout and stripe count 2.
15091         $MULTIOP $DIR/$tfile H2c ||
15092                 error "failed to create file with released layout"
15093
15094         $LFS getstripe -v $DIR/$tfile
15095
15096         local pattern=$($LFS getstripe -L $DIR/$tfile)
15097         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15098
15099         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15100                 error "getstripe"
15101         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15102         stat $DIR/$tfile || error "failed to stat released file"
15103
15104         chown $RUNAS_ID $DIR/$tfile ||
15105                 error "chown $RUNAS_ID $DIR/$tfile failed"
15106
15107         chgrp $RUNAS_ID $DIR/$tfile ||
15108                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15109
15110         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15111         rm $DIR/$tfile || error "failed to remove released file"
15112 }
15113 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15114
15115 test_230a() {
15116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15117         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15118         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15119                 skip "Need MDS version at least 2.11.52"
15120
15121         local MDTIDX=1
15122
15123         test_mkdir $DIR/$tdir
15124         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15125         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15126         [ $mdt_idx -ne 0 ] &&
15127                 error "create local directory on wrong MDT $mdt_idx"
15128
15129         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15130                         error "create remote directory failed"
15131         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15132         [ $mdt_idx -ne $MDTIDX ] &&
15133                 error "create remote directory on wrong MDT $mdt_idx"
15134
15135         createmany -o $DIR/$tdir/test_230/t- 10 ||
15136                 error "create files on remote directory failed"
15137         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15138         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15139         rm -r $DIR/$tdir || error "unlink remote directory failed"
15140 }
15141 run_test 230a "Create remote directory and files under the remote directory"
15142
15143 test_230b() {
15144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15145         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15146         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15147                 skip "Need MDS version at least 2.11.52"
15148
15149         local MDTIDX=1
15150         local mdt_index
15151         local i
15152         local file
15153         local pid
15154         local stripe_count
15155         local migrate_dir=$DIR/$tdir/migrate_dir
15156         local other_dir=$DIR/$tdir/other_dir
15157
15158         test_mkdir $DIR/$tdir
15159         test_mkdir -i0 -c1 $migrate_dir
15160         test_mkdir -i0 -c1 $other_dir
15161         for ((i=0; i<10; i++)); do
15162                 mkdir -p $migrate_dir/dir_${i}
15163                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15164                         error "create files under remote dir failed $i"
15165         done
15166
15167         cp /etc/passwd $migrate_dir/$tfile
15168         cp /etc/passwd $other_dir/$tfile
15169         chattr +SAD $migrate_dir
15170         chattr +SAD $migrate_dir/$tfile
15171
15172         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15173         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15174         local old_dir_mode=$(stat -c%f $migrate_dir)
15175         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15176
15177         mkdir -p $migrate_dir/dir_default_stripe2
15178         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15179         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15180
15181         mkdir -p $other_dir
15182         ln $migrate_dir/$tfile $other_dir/luna
15183         ln $migrate_dir/$tfile $migrate_dir/sofia
15184         ln $other_dir/$tfile $migrate_dir/david
15185         ln -s $migrate_dir/$tfile $other_dir/zachary
15186         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15187         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15188
15189         $LFS migrate -m $MDTIDX $migrate_dir ||
15190                 error "fails on migrating remote dir to MDT1"
15191
15192         echo "migratate to MDT1, then checking.."
15193         for ((i = 0; i < 10; i++)); do
15194                 for file in $(find $migrate_dir/dir_${i}); do
15195                         mdt_index=$($LFS getstripe -m $file)
15196                         [ $mdt_index == $MDTIDX ] ||
15197                                 error "$file is not on MDT${MDTIDX}"
15198                 done
15199         done
15200
15201         # the multiple link file should still in MDT0
15202         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15203         [ $mdt_index == 0 ] ||
15204                 error "$file is not on MDT${MDTIDX}"
15205
15206         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15207         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15208                 error " expect $old_dir_flag get $new_dir_flag"
15209
15210         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15211         [ "$old_file_flag" = "$new_file_flag" ] ||
15212                 error " expect $old_file_flag get $new_file_flag"
15213
15214         local new_dir_mode=$(stat -c%f $migrate_dir)
15215         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15216                 error "expect mode $old_dir_mode get $new_dir_mode"
15217
15218         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15219         [ "$old_file_mode" = "$new_file_mode" ] ||
15220                 error "expect mode $old_file_mode get $new_file_mode"
15221
15222         diff /etc/passwd $migrate_dir/$tfile ||
15223                 error "$tfile different after migration"
15224
15225         diff /etc/passwd $other_dir/luna ||
15226                 error "luna different after migration"
15227
15228         diff /etc/passwd $migrate_dir/sofia ||
15229                 error "sofia different after migration"
15230
15231         diff /etc/passwd $migrate_dir/david ||
15232                 error "david different after migration"
15233
15234         diff /etc/passwd $other_dir/zachary ||
15235                 error "zachary different after migration"
15236
15237         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15238                 error "${tfile}_ln different after migration"
15239
15240         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15241                 error "${tfile}_ln_other different after migration"
15242
15243         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15244         [ $stripe_count = 2 ] ||
15245                 error "dir strpe_count $d != 2 after migration."
15246
15247         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15248         [ $stripe_count = 2 ] ||
15249                 error "file strpe_count $d != 2 after migration."
15250
15251         #migrate back to MDT0
15252         MDTIDX=0
15253
15254         $LFS migrate -m $MDTIDX $migrate_dir ||
15255                 error "fails on migrating remote dir to MDT0"
15256
15257         echo "migrate back to MDT0, checking.."
15258         for file in $(find $migrate_dir); do
15259                 mdt_index=$($LFS getstripe -m $file)
15260                 [ $mdt_index == $MDTIDX ] ||
15261                         error "$file is not on MDT${MDTIDX}"
15262         done
15263
15264         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15265         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15266                 error " expect $old_dir_flag get $new_dir_flag"
15267
15268         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15269         [ "$old_file_flag" = "$new_file_flag" ] ||
15270                 error " expect $old_file_flag get $new_file_flag"
15271
15272         local new_dir_mode=$(stat -c%f $migrate_dir)
15273         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15274                 error "expect mode $old_dir_mode get $new_dir_mode"
15275
15276         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15277         [ "$old_file_mode" = "$new_file_mode" ] ||
15278                 error "expect mode $old_file_mode get $new_file_mode"
15279
15280         diff /etc/passwd ${migrate_dir}/$tfile ||
15281                 error "$tfile different after migration"
15282
15283         diff /etc/passwd ${other_dir}/luna ||
15284                 error "luna different after migration"
15285
15286         diff /etc/passwd ${migrate_dir}/sofia ||
15287                 error "sofia different after migration"
15288
15289         diff /etc/passwd ${other_dir}/zachary ||
15290                 error "zachary different after migration"
15291
15292         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15293                 error "${tfile}_ln different after migration"
15294
15295         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15296                 error "${tfile}_ln_other different after migration"
15297
15298         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15299         [ $stripe_count = 2 ] ||
15300                 error "dir strpe_count $d != 2 after migration."
15301
15302         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15303         [ $stripe_count = 2 ] ||
15304                 error "file strpe_count $d != 2 after migration."
15305
15306         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15307 }
15308 run_test 230b "migrate directory"
15309
15310 test_230c() {
15311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15312         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15313         remote_mds_nodsh && skip "remote MDS with nodsh"
15314         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15315                 skip "Need MDS version at least 2.11.52"
15316
15317         local MDTIDX=1
15318         local total=3
15319         local mdt_index
15320         local file
15321         local migrate_dir=$DIR/$tdir/migrate_dir
15322
15323         #If migrating directory fails in the middle, all entries of
15324         #the directory is still accessiable.
15325         test_mkdir $DIR/$tdir
15326         test_mkdir -i0 -c1 $migrate_dir
15327         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15328         stat $migrate_dir
15329         createmany -o $migrate_dir/f $total ||
15330                 error "create files under ${migrate_dir} failed"
15331
15332         # fail after migrating top dir, and this will fail only once, so the
15333         # first sub file migration will fail (currently f3), others succeed.
15334         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15335         do_facet mds1 lctl set_param fail_loc=0x1801
15336         local t=$(ls $migrate_dir | wc -l)
15337         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15338                 error "migrate should fail"
15339         local u=$(ls $migrate_dir | wc -l)
15340         [ "$u" == "$t" ] || error "$u != $t during migration"
15341
15342         # add new dir/file should succeed
15343         mkdir $migrate_dir/dir ||
15344                 error "mkdir failed under migrating directory"
15345         touch $migrate_dir/file ||
15346                 error "create file failed under migrating directory"
15347
15348         # add file with existing name should fail
15349         for file in $migrate_dir/f*; do
15350                 stat $file > /dev/null || error "stat $file failed"
15351                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15352                         error "open(O_CREAT|O_EXCL) $file should fail"
15353                 $MULTIOP $file m && error "create $file should fail"
15354                 touch $DIR/$tdir/remote_dir/$tfile ||
15355                         error "touch $tfile failed"
15356                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15357                         error "link $file should fail"
15358                 mdt_index=$($LFS getstripe -m $file)
15359                 if [ $mdt_index == 0 ]; then
15360                         # file failed to migrate is not allowed to rename to
15361                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15362                                 error "rename to $file should fail"
15363                 else
15364                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15365                                 error "rename to $file failed"
15366                 fi
15367                 echo hello >> $file || error "write $file failed"
15368         done
15369
15370         # resume migration with different options should fail
15371         $LFS migrate -m 0 $migrate_dir &&
15372                 error "migrate -m 0 $migrate_dir should fail"
15373
15374         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15375                 error "migrate -c 2 $migrate_dir should fail"
15376
15377         # resume migration should succeed
15378         $LFS migrate -m $MDTIDX $migrate_dir ||
15379                 error "migrate $migrate_dir failed"
15380
15381         echo "Finish migration, then checking.."
15382         for file in $(find $migrate_dir); do
15383                 mdt_index=$($LFS getstripe -m $file)
15384                 [ $mdt_index == $MDTIDX ] ||
15385                         error "$file is not on MDT${MDTIDX}"
15386         done
15387
15388         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15389 }
15390 run_test 230c "check directory accessiblity if migration failed"
15391
15392 test_230d() {
15393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15394         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15395         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15396                 skip "Need MDS version at least 2.11.52"
15397         # LU-11235
15398         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15399
15400         local migrate_dir=$DIR/$tdir/migrate_dir
15401         local old_index
15402         local new_index
15403         local old_count
15404         local new_count
15405         local new_hash
15406         local mdt_index
15407         local i
15408         local j
15409
15410         old_index=$((RANDOM % MDSCOUNT))
15411         old_count=$((MDSCOUNT - old_index))
15412         new_index=$((RANDOM % MDSCOUNT))
15413         new_count=$((MDSCOUNT - new_index))
15414         new_hash="all_char"
15415
15416         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15417         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15418
15419         test_mkdir $DIR/$tdir
15420         test_mkdir -i $old_index -c $old_count $migrate_dir
15421
15422         for ((i=0; i<100; i++)); do
15423                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15424                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15425                         error "create files under remote dir failed $i"
15426         done
15427
15428         echo -n "Migrate from MDT$old_index "
15429         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15430         echo -n "to MDT$new_index"
15431         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
15432         echo
15433
15434         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
15435         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
15436                 error "migrate remote dir error"
15437
15438         echo "Finish migration, then checking.."
15439         for file in $(find $migrate_dir); do
15440                 mdt_index=$($LFS getstripe -m $file)
15441                 if [ $mdt_index -lt $new_index ] ||
15442                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
15443                         error "$file is on MDT$mdt_index"
15444                 fi
15445         done
15446
15447         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15448 }
15449 run_test 230d "check migrate big directory"
15450
15451 test_230e() {
15452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15453         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15454         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15455                 skip "Need MDS version at least 2.11.52"
15456
15457         local i
15458         local j
15459         local a_fid
15460         local b_fid
15461
15462         mkdir -p $DIR/$tdir
15463         mkdir $DIR/$tdir/migrate_dir
15464         mkdir $DIR/$tdir/other_dir
15465         touch $DIR/$tdir/migrate_dir/a
15466         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
15467         ls $DIR/$tdir/other_dir
15468
15469         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15470                 error "migrate dir fails"
15471
15472         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15473         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15474
15475         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15476         [ $mdt_index == 0 ] || error "a is not on MDT0"
15477
15478         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
15479                 error "migrate dir fails"
15480
15481         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
15482         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
15483
15484         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15485         [ $mdt_index == 1 ] || error "a is not on MDT1"
15486
15487         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
15488         [ $mdt_index == 1 ] || error "b is not on MDT1"
15489
15490         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15491         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
15492
15493         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
15494
15495         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15496 }
15497 run_test 230e "migrate mulitple local link files"
15498
15499 test_230f() {
15500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15501         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15502         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15503                 skip "Need MDS version at least 2.11.52"
15504
15505         local a_fid
15506         local ln_fid
15507
15508         mkdir -p $DIR/$tdir
15509         mkdir $DIR/$tdir/migrate_dir
15510         $LFS mkdir -i1 $DIR/$tdir/other_dir
15511         touch $DIR/$tdir/migrate_dir/a
15512         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
15513         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
15514         ls $DIR/$tdir/other_dir
15515
15516         # a should be migrated to MDT1, since no other links on MDT0
15517         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15518                 error "#1 migrate dir fails"
15519         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15520         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15521         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15522         [ $mdt_index == 1 ] || error "a is not on MDT1"
15523
15524         # a should stay on MDT1, because it is a mulitple link file
15525         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15526                 error "#2 migrate dir fails"
15527         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15528         [ $mdt_index == 1 ] || error "a is not on MDT1"
15529
15530         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15531                 error "#3 migrate dir fails"
15532
15533         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15534         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
15535         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
15536
15537         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
15538         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
15539
15540         # a should be migrated to MDT0, since no other links on MDT1
15541         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15542                 error "#4 migrate dir fails"
15543         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15544         [ $mdt_index == 0 ] || error "a is not on MDT0"
15545
15546         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15547 }
15548 run_test 230f "migrate mulitple remote link files"
15549
15550 test_230g() {
15551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15552         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15553         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15554                 skip "Need MDS version at least 2.11.52"
15555
15556         mkdir -p $DIR/$tdir/migrate_dir
15557
15558         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
15559                 error "migrating dir to non-exist MDT succeeds"
15560         true
15561 }
15562 run_test 230g "migrate dir to non-exist MDT"
15563
15564 test_230h() {
15565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15566         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15567         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15568                 skip "Need MDS version at least 2.11.52"
15569
15570         local mdt_index
15571
15572         mkdir -p $DIR/$tdir/migrate_dir
15573
15574         $LFS migrate -m1 $DIR &&
15575                 error "migrating mountpoint1 should fail"
15576
15577         $LFS migrate -m1 $DIR/$tdir/.. &&
15578                 error "migrating mountpoint2 should fail"
15579
15580         # same as mv
15581         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
15582                 error "migrating $tdir/migrate_dir/.. should fail"
15583
15584         true
15585 }
15586 run_test 230h "migrate .. and root"
15587
15588 test_230i() {
15589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15590         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15591         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15592                 skip "Need MDS version at least 2.11.52"
15593
15594         mkdir -p $DIR/$tdir/migrate_dir
15595
15596         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
15597                 error "migration fails with a tailing slash"
15598
15599         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
15600                 error "migration fails with two tailing slashes"
15601 }
15602 run_test 230i "lfs migrate -m tolerates trailing slashes"
15603
15604 test_230j() {
15605         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15606         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15607                 skip "Need MDS version at least 2.11.52"
15608
15609         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
15610         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
15611                 error "create $tfile failed"
15612         cat /etc/passwd > $DIR/$tdir/$tfile
15613
15614         $LFS migrate -m 1 $DIR/$tdir
15615
15616         cmp /etc/passwd $DIR/$tdir/$tfile ||
15617                 error "DoM file mismatch after migration"
15618 }
15619 run_test 230j "DoM file data not changed after dir migration"
15620
15621 test_230k() {
15622         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
15623         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15624                 skip "Need MDS version at least 2.11.56"
15625
15626         local total=20
15627         local files_on_starting_mdt=0
15628
15629         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
15630         $LFS getdirstripe $DIR/$tdir
15631         for i in $(seq $total); do
15632                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
15633                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15634                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15635         done
15636
15637         echo "$files_on_starting_mdt files on MDT0"
15638
15639         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
15640         $LFS getdirstripe $DIR/$tdir
15641
15642         files_on_starting_mdt=0
15643         for i in $(seq $total); do
15644                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15645                         error "file $tfile.$i mismatch after migration"
15646                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
15647                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15648         done
15649
15650         echo "$files_on_starting_mdt files on MDT1 after migration"
15651         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
15652
15653         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
15654         $LFS getdirstripe $DIR/$tdir
15655
15656         files_on_starting_mdt=0
15657         for i in $(seq $total); do
15658                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15659                         error "file $tfile.$i mismatch after 2nd migration"
15660                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15661                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15662         done
15663
15664         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
15665         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
15666
15667         true
15668 }
15669 run_test 230k "file data not changed after dir migration"
15670
15671 test_230l() {
15672         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15673         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15674                 skip "Need MDS version at least 2.11.56"
15675
15676         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
15677         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
15678                 error "create files under remote dir failed $i"
15679         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
15680 }
15681 run_test 230l "readdir between MDTs won't crash"
15682
15683 test_231a()
15684 {
15685         # For simplicity this test assumes that max_pages_per_rpc
15686         # is the same across all OSCs
15687         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
15688         local bulk_size=$((max_pages * PAGE_SIZE))
15689         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
15690                                        head -n 1)
15691
15692         mkdir -p $DIR/$tdir
15693         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
15694                 error "failed to set stripe with -S ${brw_size}M option"
15695
15696         # clear the OSC stats
15697         $LCTL set_param osc.*.stats=0 &>/dev/null
15698         stop_writeback
15699
15700         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
15701         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
15702                 oflag=direct &>/dev/null || error "dd failed"
15703
15704         sync; sleep 1; sync # just to be safe
15705         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
15706         if [ x$nrpcs != "x1" ]; then
15707                 $LCTL get_param osc.*.stats
15708                 error "found $nrpcs ost_write RPCs, not 1 as expected"
15709         fi
15710
15711         start_writeback
15712         # Drop the OSC cache, otherwise we will read from it
15713         cancel_lru_locks osc
15714
15715         # clear the OSC stats
15716         $LCTL set_param osc.*.stats=0 &>/dev/null
15717
15718         # Client reads $bulk_size.
15719         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
15720                 iflag=direct &>/dev/null || error "dd failed"
15721
15722         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
15723         if [ x$nrpcs != "x1" ]; then
15724                 $LCTL get_param osc.*.stats
15725                 error "found $nrpcs ost_read RPCs, not 1 as expected"
15726         fi
15727 }
15728 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
15729
15730 test_231b() {
15731         mkdir -p $DIR/$tdir
15732         local i
15733         for i in {0..1023}; do
15734                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
15735                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
15736                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
15737         done
15738         sync
15739 }
15740 run_test 231b "must not assert on fully utilized OST request buffer"
15741
15742 test_232a() {
15743         mkdir -p $DIR/$tdir
15744         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15745
15746         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15747         do_facet ost1 $LCTL set_param fail_loc=0x31c
15748
15749         # ignore dd failure
15750         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
15751
15752         do_facet ost1 $LCTL set_param fail_loc=0
15753         umount_client $MOUNT || error "umount failed"
15754         mount_client $MOUNT || error "mount failed"
15755         stop ost1 || error "cannot stop ost1"
15756         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15757 }
15758 run_test 232a "failed lock should not block umount"
15759
15760 test_232b() {
15761         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
15762                 skip "Need MDS version at least 2.10.58"
15763
15764         mkdir -p $DIR/$tdir
15765         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15766         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
15767         sync
15768         cancel_lru_locks osc
15769
15770         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15771         do_facet ost1 $LCTL set_param fail_loc=0x31c
15772
15773         # ignore failure
15774         $LFS data_version $DIR/$tdir/$tfile || true
15775
15776         do_facet ost1 $LCTL set_param fail_loc=0
15777         umount_client $MOUNT || error "umount failed"
15778         mount_client $MOUNT || error "mount failed"
15779         stop ost1 || error "cannot stop ost1"
15780         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15781 }
15782 run_test 232b "failed data version lock should not block umount"
15783
15784 test_233a() {
15785         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
15786                 skip "Need MDS version at least 2.3.64"
15787         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15788
15789         local fid=$($LFS path2fid $MOUNT)
15790
15791         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15792                 error "cannot access $MOUNT using its FID '$fid'"
15793 }
15794 run_test 233a "checking that OBF of the FS root succeeds"
15795
15796 test_233b() {
15797         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
15798                 skip "Need MDS version at least 2.5.90"
15799         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15800
15801         local fid=$($LFS path2fid $MOUNT/.lustre)
15802
15803         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15804                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
15805
15806         fid=$($LFS path2fid $MOUNT/.lustre/fid)
15807         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15808                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
15809 }
15810 run_test 233b "checking that OBF of the FS .lustre succeeds"
15811
15812 test_234() {
15813         local p="$TMP/sanityN-$TESTNAME.parameters"
15814         save_lustre_params client "llite.*.xattr_cache" > $p
15815         lctl set_param llite.*.xattr_cache 1 ||
15816                 skip_env "xattr cache is not supported"
15817
15818         mkdir -p $DIR/$tdir || error "mkdir failed"
15819         touch $DIR/$tdir/$tfile || error "touch failed"
15820         # OBD_FAIL_LLITE_XATTR_ENOMEM
15821         $LCTL set_param fail_loc=0x1405
15822         getfattr -n user.attr $DIR/$tdir/$tfile &&
15823                 error "getfattr should have failed with ENOMEM"
15824         $LCTL set_param fail_loc=0x0
15825         rm -rf $DIR/$tdir
15826
15827         restore_lustre_params < $p
15828         rm -f $p
15829 }
15830 run_test 234 "xattr cache should not crash on ENOMEM"
15831
15832 test_235() {
15833         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
15834                 skip "Need MDS version at least 2.4.52"
15835
15836         flock_deadlock $DIR/$tfile
15837         local RC=$?
15838         case $RC in
15839                 0)
15840                 ;;
15841                 124) error "process hangs on a deadlock"
15842                 ;;
15843                 *) error "error executing flock_deadlock $DIR/$tfile"
15844                 ;;
15845         esac
15846 }
15847 run_test 235 "LU-1715: flock deadlock detection does not work properly"
15848
15849 #LU-2935
15850 test_236() {
15851         check_swap_layouts_support
15852
15853         local ref1=/etc/passwd
15854         local ref2=/etc/group
15855         local file1=$DIR/$tdir/f1
15856         local file2=$DIR/$tdir/f2
15857
15858         test_mkdir -c1 $DIR/$tdir
15859         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
15860         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
15861         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
15862         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
15863         local fd=$(free_fd)
15864         local cmd="exec $fd<>$file2"
15865         eval $cmd
15866         rm $file2
15867         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
15868                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
15869         cmd="exec $fd>&-"
15870         eval $cmd
15871         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15872
15873         #cleanup
15874         rm -rf $DIR/$tdir
15875 }
15876 run_test 236 "Layout swap on open unlinked file"
15877
15878 # LU-4659 linkea consistency
15879 test_238() {
15880         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15881                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15882                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15883                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15884
15885         touch $DIR/$tfile
15886         ln $DIR/$tfile $DIR/$tfile.lnk
15887         touch $DIR/$tfile.new
15888         mv $DIR/$tfile.new $DIR/$tfile
15889         local fid1=$($LFS path2fid $DIR/$tfile)
15890         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
15891         local path1=$($LFS fid2path $FSNAME "$fid1")
15892         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
15893         local path2=$($LFS fid2path $FSNAME "$fid2")
15894         [ $tfile.lnk == $path2 ] ||
15895                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
15896         rm -f $DIR/$tfile*
15897 }
15898 run_test 238 "Verify linkea consistency"
15899
15900 test_239A() { # was test_239
15901         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
15902                 skip "Need MDS version at least 2.5.60"
15903
15904         local list=$(comma_list $(mdts_nodes))
15905
15906         mkdir -p $DIR/$tdir
15907         createmany -o $DIR/$tdir/f- 5000
15908         unlinkmany $DIR/$tdir/f- 5000
15909         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
15910                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
15911         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
15912                         osp.*MDT*.sync_in_flight" | calc_sum)
15913         [ "$changes" -eq 0 ] || error "$changes not synced"
15914 }
15915 run_test 239A "osp_sync test"
15916
15917 test_239a() { #LU-5297
15918         remote_mds_nodsh && skip "remote MDS with nodsh"
15919
15920         touch $DIR/$tfile
15921         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
15922         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
15923         chgrp $RUNAS_GID $DIR/$tfile
15924         wait_delete_completed
15925 }
15926 run_test 239a "process invalid osp sync record correctly"
15927
15928 test_239b() { #LU-5297
15929         remote_mds_nodsh && skip "remote MDS with nodsh"
15930
15931         touch $DIR/$tfile1
15932         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
15933         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
15934         chgrp $RUNAS_GID $DIR/$tfile1
15935         wait_delete_completed
15936         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15937         touch $DIR/$tfile2
15938         chgrp $RUNAS_GID $DIR/$tfile2
15939         wait_delete_completed
15940 }
15941 run_test 239b "process osp sync record with ENOMEM error correctly"
15942
15943 test_240() {
15944         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15945         remote_mds_nodsh && skip "remote MDS with nodsh"
15946
15947         mkdir -p $DIR/$tdir
15948
15949         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
15950                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
15951         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
15952                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
15953
15954         umount_client $MOUNT || error "umount failed"
15955         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
15956         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
15957         mount_client $MOUNT || error "failed to mount client"
15958
15959         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
15960         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
15961 }
15962 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
15963
15964 test_241_bio() {
15965         local count=$1
15966         local bsize=$2
15967
15968         for LOOP in $(seq $count); do
15969                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
15970                 cancel_lru_locks $OSC || true
15971         done
15972 }
15973
15974 test_241_dio() {
15975         local count=$1
15976         local bsize=$2
15977
15978         for LOOP in $(seq $1); do
15979                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
15980                         2>/dev/null
15981         done
15982 }
15983
15984 test_241a() { # was test_241
15985         local bsize=$PAGE_SIZE
15986
15987         (( bsize < 40960 )) && bsize=40960
15988         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
15989         ls -la $DIR/$tfile
15990         cancel_lru_locks $OSC
15991         test_241_bio 1000 $bsize &
15992         PID=$!
15993         test_241_dio 1000 $bsize
15994         wait $PID
15995 }
15996 run_test 241a "bio vs dio"
15997
15998 test_241b() {
15999         local bsize=$PAGE_SIZE
16000
16001         (( bsize < 40960 )) && bsize=40960
16002         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16003         ls -la $DIR/$tfile
16004         test_241_dio 1000 $bsize &
16005         PID=$!
16006         test_241_dio 1000 $bsize
16007         wait $PID
16008 }
16009 run_test 241b "dio vs dio"
16010
16011 test_242() {
16012         remote_mds_nodsh && skip "remote MDS with nodsh"
16013
16014         mkdir -p $DIR/$tdir
16015         touch $DIR/$tdir/$tfile
16016
16017         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16018         do_facet mds1 lctl set_param fail_loc=0x105
16019         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16020
16021         do_facet mds1 lctl set_param fail_loc=0
16022         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16023 }
16024 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16025
16026 test_243()
16027 {
16028         test_mkdir $DIR/$tdir
16029         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16030 }
16031 run_test 243 "various group lock tests"
16032
16033 test_244()
16034 {
16035         test_mkdir $DIR/$tdir
16036         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16037         sendfile_grouplock $DIR/$tdir/$tfile || \
16038                 error "sendfile+grouplock failed"
16039         rm -rf $DIR/$tdir
16040 }
16041 run_test 244 "sendfile with group lock tests"
16042
16043 test_245() {
16044         local flagname="multi_mod_rpcs"
16045         local connect_data_name="max_mod_rpcs"
16046         local out
16047
16048         # check if multiple modify RPCs flag is set
16049         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16050                 grep "connect_flags:")
16051         echo "$out"
16052
16053         echo "$out" | grep -qw $flagname
16054         if [ $? -ne 0 ]; then
16055                 echo "connect flag $flagname is not set"
16056                 return
16057         fi
16058
16059         # check if multiple modify RPCs data is set
16060         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16061         echo "$out"
16062
16063         echo "$out" | grep -qw $connect_data_name ||
16064                 error "import should have connect data $connect_data_name"
16065 }
16066 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16067
16068 test_246() { # LU-7371
16069         remote_ost_nodsh && skip "remote OST with nodsh"
16070         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16071                 skip "Need OST version >= 2.7.62"
16072
16073         do_facet ost1 $LCTL set_param fail_val=4095
16074 #define OBD_FAIL_OST_READ_SIZE          0x234
16075         do_facet ost1 $LCTL set_param fail_loc=0x234
16076         $LFS setstripe $DIR/$tfile -i 0 -c 1
16077         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16078         cancel_lru_locks $FSNAME-OST0000
16079         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16080 }
16081 run_test 246 "Read file of size 4095 should return right length"
16082
16083 cleanup_247() {
16084         local submount=$1
16085
16086         trap 0
16087         umount_client $submount
16088         rmdir $submount
16089 }
16090
16091 test_247a() {
16092         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16093                 grep -q subtree ||
16094                 skip_env "Fileset feature is not supported"
16095
16096         local submount=${MOUNT}_$tdir
16097
16098         mkdir $MOUNT/$tdir
16099         mkdir -p $submount || error "mkdir $submount failed"
16100         FILESET="$FILESET/$tdir" mount_client $submount ||
16101                 error "mount $submount failed"
16102         trap "cleanup_247 $submount" EXIT
16103         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16104         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16105                 error "read $MOUNT/$tdir/$tfile failed"
16106         cleanup_247 $submount
16107 }
16108 run_test 247a "mount subdir as fileset"
16109
16110 test_247b() {
16111         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16112                 skip_env "Fileset feature is not supported"
16113
16114         local submount=${MOUNT}_$tdir
16115
16116         rm -rf $MOUNT/$tdir
16117         mkdir -p $submount || error "mkdir $submount failed"
16118         SKIP_FILESET=1
16119         FILESET="$FILESET/$tdir" mount_client $submount &&
16120                 error "mount $submount should fail"
16121         rmdir $submount
16122 }
16123 run_test 247b "mount subdir that dose not exist"
16124
16125 test_247c() {
16126         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16127                 skip_env "Fileset feature is not supported"
16128
16129         local submount=${MOUNT}_$tdir
16130
16131         mkdir -p $MOUNT/$tdir/dir1
16132         mkdir -p $submount || error "mkdir $submount failed"
16133         trap "cleanup_247 $submount" EXIT
16134         FILESET="$FILESET/$tdir" mount_client $submount ||
16135                 error "mount $submount failed"
16136         local fid=$($LFS path2fid $MOUNT/)
16137         $LFS fid2path $submount $fid && error "fid2path should fail"
16138         cleanup_247 $submount
16139 }
16140 run_test 247c "running fid2path outside root"
16141
16142 test_247d() {
16143         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16144                 skip "Fileset feature is not supported"
16145
16146         local submount=${MOUNT}_$tdir
16147
16148         mkdir -p $MOUNT/$tdir/dir1
16149         mkdir -p $submount || error "mkdir $submount failed"
16150         FILESET="$FILESET/$tdir" mount_client $submount ||
16151                 error "mount $submount failed"
16152         trap "cleanup_247 $submount" EXIT
16153         local fid=$($LFS path2fid $submount/dir1)
16154         $LFS fid2path $submount $fid || error "fid2path should succeed"
16155         cleanup_247 $submount
16156 }
16157 run_test 247d "running fid2path inside root"
16158
16159 # LU-8037
16160 test_247e() {
16161         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16162                 grep -q subtree ||
16163                 skip "Fileset feature is not supported"
16164
16165         local submount=${MOUNT}_$tdir
16166
16167         mkdir $MOUNT/$tdir
16168         mkdir -p $submount || error "mkdir $submount failed"
16169         FILESET="$FILESET/.." mount_client $submount &&
16170                 error "mount $submount should fail"
16171         rmdir $submount
16172 }
16173 run_test 247e "mount .. as fileset"
16174
16175 test_248() {
16176         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16177         [ -z "$fast_read_sav" ] && skip "no fast read support"
16178
16179         # create a large file for fast read verification
16180         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16181
16182         # make sure the file is created correctly
16183         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16184                 { rm -f $DIR/$tfile; skip "file creation error"; }
16185
16186         echo "Test 1: verify that fast read is 4 times faster on cache read"
16187
16188         # small read with fast read enabled
16189         $LCTL set_param -n llite.*.fast_read=1
16190         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16191                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16192                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16193         # small read with fast read disabled
16194         $LCTL set_param -n llite.*.fast_read=0
16195         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16196                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16197                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16198
16199         # verify that fast read is 4 times faster for cache read
16200         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16201                 error_not_in_vm "fast read was not 4 times faster: " \
16202                            "$t_fast vs $t_slow"
16203
16204         echo "Test 2: verify the performance between big and small read"
16205         $LCTL set_param -n llite.*.fast_read=1
16206
16207         # 1k non-cache read
16208         cancel_lru_locks osc
16209         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16210                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16211                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16212
16213         # 1M non-cache read
16214         cancel_lru_locks osc
16215         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16216                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16217                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16218
16219         # verify that big IO is not 4 times faster than small IO
16220         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16221                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16222
16223         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16224         rm -f $DIR/$tfile
16225 }
16226 run_test 248 "fast read verification"
16227
16228 test_249() { # LU-7890
16229         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16230                 skip "Need at least version 2.8.54"
16231
16232         rm -f $DIR/$tfile
16233         $LFS setstripe -c 1 $DIR/$tfile
16234         # Offset 2T == 4k * 512M
16235         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16236                 error "dd to 2T offset failed"
16237 }
16238 run_test 249 "Write above 2T file size"
16239
16240 test_250() {
16241         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16242          && skip "no 16TB file size limit on ZFS"
16243
16244         $LFS setstripe -c 1 $DIR/$tfile
16245         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16246         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16247         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16248         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16249                 conv=notrunc,fsync && error "append succeeded"
16250         return 0
16251 }
16252 run_test 250 "Write above 16T limit"
16253
16254 test_251() {
16255         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16256
16257         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16258         #Skip once - writing the first stripe will succeed
16259         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16260         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16261                 error "short write happened"
16262
16263         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16264         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16265                 error "short read happened"
16266
16267         rm -f $DIR/$tfile
16268 }
16269 run_test 251 "Handling short read and write correctly"
16270
16271 test_252() {
16272         remote_mds_nodsh && skip "remote MDS with nodsh"
16273         remote_ost_nodsh && skip "remote OST with nodsh"
16274         if [ "$ost1_FSTYPE" != "ldiskfs" -o "$mds1_FSTYPE" != "ldiskfs" ]; then
16275                 skip_env "ldiskfs only test"
16276         fi
16277
16278         local tgt
16279         local dev
16280         local out
16281         local uuid
16282         local num
16283         local gen
16284
16285         # check lr_reader on OST0000
16286         tgt=ost1
16287         dev=$(facet_device $tgt)
16288         out=$(do_facet $tgt $LR_READER $dev)
16289         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16290         echo "$out"
16291         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16292         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16293                 error "Invalid uuid returned by $LR_READER on target $tgt"
16294         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16295
16296         # check lr_reader -c on MDT0000
16297         tgt=mds1
16298         dev=$(facet_device $tgt)
16299         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16300                 skip "$LR_READER does not support additional options"
16301         fi
16302         out=$(do_facet $tgt $LR_READER -c $dev)
16303         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16304         echo "$out"
16305         num=$(echo "$out" | grep -c "mdtlov")
16306         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16307                 error "Invalid number of mdtlov clients returned by $LR_READER"
16308         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16309
16310         # check lr_reader -cr on MDT0000
16311         out=$(do_facet $tgt $LR_READER -cr $dev)
16312         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16313         echo "$out"
16314         echo "$out" | grep -q "^reply_data:$" ||
16315                 error "$LR_READER should have returned 'reply_data' section"
16316         num=$(echo "$out" | grep -c "client_generation")
16317         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16318 }
16319 run_test 252 "check lr_reader tool"
16320
16321 test_253_fill_ost() {
16322         local size_mb #how many MB should we write to pass watermark
16323         local lwm=$3  #low watermark
16324         local free_10mb #10% of free space
16325
16326         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16327         size_mb=$((free_kb / 1024 - lwm))
16328         free_10mb=$((free_kb / 10240))
16329         #If 10% of free space cross low watermark use it
16330         if (( free_10mb > size_mb )); then
16331                 size_mb=$free_10mb
16332         else
16333                 #At least we need to store 1.1 of difference between
16334                 #free space and low watermark
16335                 size_mb=$((size_mb + size_mb / 10))
16336         fi
16337         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
16338                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
16339                          oflag=append conv=notrunc
16340         fi
16341
16342         sleep_maxage
16343
16344         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16345         echo "OST still has $((free_kb / 1024)) mbytes free"
16346 }
16347
16348 test_253() {
16349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16350         remote_mds_nodsh && skip "remote MDS with nodsh"
16351         remote_mgs_nodsh && skip "remote MGS with nodsh"
16352
16353         local ostidx=0
16354         local rc=0
16355
16356         local ost_name=$($LFS osts |
16357                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
16358         # on the mdt's osc
16359         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16360         do_facet $SINGLEMDS $LCTL get_param -n \
16361                 osp.$mdtosc_proc1.reserved_mb_high ||
16362                 skip  "remote MDS does not support reserved_mb_high"
16363
16364         rm -rf $DIR/$tdir
16365         wait_mds_ost_sync
16366         wait_delete_completed
16367         mkdir $DIR/$tdir
16368
16369         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
16370                         osp.$mdtosc_proc1.reserved_mb_high)
16371         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
16372                         osp.$mdtosc_proc1.reserved_mb_low)
16373         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
16374
16375         if ! combined_mgs_mds ; then
16376                 mount_mgs_client
16377         fi
16378         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
16379         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
16380                 error "Adding $ost_name to pool failed"
16381
16382         # Wait for client to see a OST at pool
16383         wait_update $HOSTNAME "$LCTL get_param -n
16384                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
16385                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
16386                 error "Client can not see the pool"
16387         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16388                 error "Setstripe failed"
16389
16390         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
16391         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
16392         echo "OST still has $((blocks/1024)) mbytes free"
16393
16394         local new_lwm=$((blocks/1024-10))
16395         do_facet $SINGLEMDS $LCTL set_param \
16396                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
16397         do_facet $SINGLEMDS $LCTL set_param \
16398                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
16399
16400         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16401
16402         #First enospc could execute orphan deletion so repeat.
16403         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16404
16405         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16406                         osp.$mdtosc_proc1.prealloc_status)
16407         echo "prealloc_status $oa_status"
16408
16409         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
16410                 error "File creation should fail"
16411         #object allocation was stopped, but we still able to append files
16412         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
16413                 error "Append failed"
16414         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
16415
16416         wait_delete_completed
16417
16418         sleep_maxage
16419
16420         for i in $(seq 10 12); do
16421                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
16422                         error "File creation failed after rm";
16423         done
16424
16425         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16426                         osp.$mdtosc_proc1.prealloc_status)
16427         echo "prealloc_status $oa_status"
16428
16429         if (( oa_status != 0 )); then
16430                 error "Object allocation still disable after rm"
16431         fi
16432         do_facet $SINGLEMDS $LCTL set_param \
16433                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
16434         do_facet $SINGLEMDS $LCTL set_param \
16435                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
16436
16437
16438         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
16439                 error "Remove $ost_name from pool failed"
16440         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16441                 error "Pool destroy fialed"
16442
16443         if ! combined_mgs_mds ; then
16444                 umount_mgs_client
16445         fi
16446 }
16447 run_test 253 "Check object allocation limit"
16448
16449 test_254() {
16450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16451         remote_mds_nodsh && skip "remote MDS with nodsh"
16452         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
16453                 skip "MDS does not support changelog_size"
16454
16455         local cl_user
16456         local MDT0=$(facet_svc $SINGLEMDS)
16457
16458         changelog_register || error "changelog_register failed"
16459
16460         changelog_clear 0 || error "changelog_clear failed"
16461
16462         local size1=$(do_facet $SINGLEMDS \
16463                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16464         echo "Changelog size $size1"
16465
16466         rm -rf $DIR/$tdir
16467         $LFS mkdir -i 0 $DIR/$tdir
16468         # change something
16469         mkdir -p $DIR/$tdir/pics/2008/zachy
16470         touch $DIR/$tdir/pics/2008/zachy/timestamp
16471         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
16472         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16473         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16474         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16475         rm $DIR/$tdir/pics/desktop.jpg
16476
16477         local size2=$(do_facet $SINGLEMDS \
16478                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16479         echo "Changelog size after work $size2"
16480
16481         (( $size2 > $size1 )) ||
16482                 error "new Changelog size=$size2 less than old size=$size1"
16483 }
16484 run_test 254 "Check changelog size"
16485
16486 ladvise_no_type()
16487 {
16488         local type=$1
16489         local file=$2
16490
16491         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
16492                 awk -F: '{print $2}' | grep $type > /dev/null
16493         if [ $? -ne 0 ]; then
16494                 return 0
16495         fi
16496         return 1
16497 }
16498
16499 ladvise_no_ioctl()
16500 {
16501         local file=$1
16502
16503         lfs ladvise -a willread $file > /dev/null 2>&1
16504         if [ $? -eq 0 ]; then
16505                 return 1
16506         fi
16507
16508         lfs ladvise -a willread $file 2>&1 |
16509                 grep "Inappropriate ioctl for device" > /dev/null
16510         if [ $? -eq 0 ]; then
16511                 return 0
16512         fi
16513         return 1
16514 }
16515
16516 percent() {
16517         bc <<<"scale=2; ($1 - $2) * 100 / $2"
16518 }
16519
16520 # run a random read IO workload
16521 # usage: random_read_iops <filename> <filesize> <iosize>
16522 random_read_iops() {
16523         local file=$1
16524         local fsize=$2
16525         local iosize=${3:-4096}
16526
16527         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
16528                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
16529 }
16530
16531 drop_file_oss_cache() {
16532         local file="$1"
16533         local nodes="$2"
16534
16535         $LFS ladvise -a dontneed $file 2>/dev/null ||
16536                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
16537 }
16538
16539 ladvise_willread_performance()
16540 {
16541         local repeat=10
16542         local average_origin=0
16543         local average_cache=0
16544         local average_ladvise=0
16545
16546         for ((i = 1; i <= $repeat; i++)); do
16547                 echo "Iter $i/$repeat: reading without willread hint"
16548                 cancel_lru_locks osc
16549                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16550                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
16551                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
16552                 average_origin=$(bc <<<"$average_origin + $speed_origin")
16553
16554                 cancel_lru_locks osc
16555                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
16556                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
16557                 average_cache=$(bc <<<"$average_cache + $speed_cache")
16558
16559                 cancel_lru_locks osc
16560                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16561                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
16562                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
16563                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
16564                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
16565         done
16566         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
16567         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
16568         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
16569
16570         speedup_cache=$(percent $average_cache $average_origin)
16571         speedup_ladvise=$(percent $average_ladvise $average_origin)
16572
16573         echo "Average uncached read: $average_origin"
16574         echo "Average speedup with OSS cached read: " \
16575                 "$average_cache = +$speedup_cache%"
16576         echo "Average speedup with ladvise willread: " \
16577                 "$average_ladvise = +$speedup_ladvise%"
16578
16579         local lowest_speedup=20
16580         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
16581                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
16582                         "got $average_cache%. Skipping ladvise willread check."
16583                 return 0
16584         fi
16585
16586         # the test won't work on ZFS until it supports 'ladvise dontneed', but
16587         # it is still good to run until then to exercise 'ladvise willread'
16588         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16589                 [ "$ost1_FSTYPE" = "zfs" ] &&
16590                 echo "osd-zfs does not support dontneed or drop_caches" &&
16591                 return 0
16592
16593         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
16594         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
16595                 error_not_in_vm "Speedup with willread is less than " \
16596                         "$lowest_speedup%, got $average_ladvise%"
16597 }
16598
16599 test_255a() {
16600         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16601                 skip "lustre < 2.8.54 does not support ladvise "
16602         remote_ost_nodsh && skip "remote OST with nodsh"
16603
16604         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
16605
16606         ladvise_no_type willread $DIR/$tfile &&
16607                 skip "willread ladvise is not supported"
16608
16609         ladvise_no_ioctl $DIR/$tfile &&
16610                 skip "ladvise ioctl is not supported"
16611
16612         local size_mb=100
16613         local size=$((size_mb * 1048576))
16614         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16615                 error "dd to $DIR/$tfile failed"
16616
16617         lfs ladvise -a willread $DIR/$tfile ||
16618                 error "Ladvise failed with no range argument"
16619
16620         lfs ladvise -a willread -s 0 $DIR/$tfile ||
16621                 error "Ladvise failed with no -l or -e argument"
16622
16623         lfs ladvise -a willread -e 1 $DIR/$tfile ||
16624                 error "Ladvise failed with only -e argument"
16625
16626         lfs ladvise -a willread -l 1 $DIR/$tfile ||
16627                 error "Ladvise failed with only -l argument"
16628
16629         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
16630                 error "End offset should not be smaller than start offset"
16631
16632         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
16633                 error "End offset should not be equal to start offset"
16634
16635         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
16636                 error "Ladvise failed with overflowing -s argument"
16637
16638         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
16639                 error "Ladvise failed with overflowing -e argument"
16640
16641         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
16642                 error "Ladvise failed with overflowing -l argument"
16643
16644         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
16645                 error "Ladvise succeeded with conflicting -l and -e arguments"
16646
16647         echo "Synchronous ladvise should wait"
16648         local delay=4
16649 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
16650         do_nodes $(comma_list $(osts_nodes)) \
16651                 $LCTL set_param fail_val=$delay fail_loc=0x237
16652
16653         local start_ts=$SECONDS
16654         lfs ladvise -a willread $DIR/$tfile ||
16655                 error "Ladvise failed with no range argument"
16656         local end_ts=$SECONDS
16657         local inteval_ts=$((end_ts - start_ts))
16658
16659         if [ $inteval_ts -lt $(($delay - 1)) ]; then
16660                 error "Synchronous advice didn't wait reply"
16661         fi
16662
16663         echo "Asynchronous ladvise shouldn't wait"
16664         local start_ts=$SECONDS
16665         lfs ladvise -a willread -b $DIR/$tfile ||
16666                 error "Ladvise failed with no range argument"
16667         local end_ts=$SECONDS
16668         local inteval_ts=$((end_ts - start_ts))
16669
16670         if [ $inteval_ts -gt $(($delay / 2)) ]; then
16671                 error "Asynchronous advice blocked"
16672         fi
16673
16674         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
16675         ladvise_willread_performance
16676 }
16677 run_test 255a "check 'lfs ladvise -a willread'"
16678
16679 facet_meminfo() {
16680         local facet=$1
16681         local info=$2
16682
16683         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
16684 }
16685
16686 test_255b() {
16687         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16688                 skip "lustre < 2.8.54 does not support ladvise "
16689         remote_ost_nodsh && skip "remote OST with nodsh"
16690
16691         lfs setstripe -c 1 -i 0 $DIR/$tfile
16692
16693         ladvise_no_type dontneed $DIR/$tfile &&
16694                 skip "dontneed ladvise is not supported"
16695
16696         ladvise_no_ioctl $DIR/$tfile &&
16697                 skip "ladvise ioctl is not supported"
16698
16699         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16700                 [ "$ost1_FSTYPE" = "zfs" ] &&
16701                 skip "zfs-osd does not support 'ladvise dontneed'"
16702
16703         local size_mb=100
16704         local size=$((size_mb * 1048576))
16705         # In order to prevent disturbance of other processes, only check 3/4
16706         # of the memory usage
16707         local kibibytes=$((size_mb * 1024 * 3 / 4))
16708
16709         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16710                 error "dd to $DIR/$tfile failed"
16711
16712         #force write to complete before dropping OST cache & checking memory
16713         sync
16714
16715         local total=$(facet_meminfo ost1 MemTotal)
16716         echo "Total memory: $total KiB"
16717
16718         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
16719         local before_read=$(facet_meminfo ost1 Cached)
16720         echo "Cache used before read: $before_read KiB"
16721
16722         lfs ladvise -a willread $DIR/$tfile ||
16723                 error "Ladvise willread failed"
16724         local after_read=$(facet_meminfo ost1 Cached)
16725         echo "Cache used after read: $after_read KiB"
16726
16727         lfs ladvise -a dontneed $DIR/$tfile ||
16728                 error "Ladvise dontneed again failed"
16729         local no_read=$(facet_meminfo ost1 Cached)
16730         echo "Cache used after dontneed ladvise: $no_read KiB"
16731
16732         if [ $total -lt $((before_read + kibibytes)) ]; then
16733                 echo "Memory is too small, abort checking"
16734                 return 0
16735         fi
16736
16737         if [ $((before_read + kibibytes)) -gt $after_read ]; then
16738                 error "Ladvise willread should use more memory" \
16739                         "than $kibibytes KiB"
16740         fi
16741
16742         if [ $((no_read + kibibytes)) -gt $after_read ]; then
16743                 error "Ladvise dontneed should release more memory" \
16744                         "than $kibibytes KiB"
16745         fi
16746 }
16747 run_test 255b "check 'lfs ladvise -a dontneed'"
16748
16749 test_255c() {
16750         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
16751                 skip "lustre < 2.10.53 does not support lockahead"
16752
16753         local count
16754         local new_count
16755         local difference
16756         local i
16757         local rc
16758
16759         test_mkdir -p $DIR/$tdir
16760         $LFS setstripe -i 0 $DIR/$tdir
16761
16762         #test 10 returns only success/failure
16763         i=10
16764         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16765         rc=$?
16766         if [ $rc -eq 255 ]; then
16767                 error "Ladvise test${i} failed, ${rc}"
16768         fi
16769
16770         #test 11 counts lock enqueue requests, all others count new locks
16771         i=11
16772         count=$(do_facet ost1 \
16773                 $LCTL get_param -n ost.OSS.ost.stats)
16774         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
16775
16776         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16777         rc=$?
16778         if [ $rc -eq 255 ]; then
16779                 error "Ladvise test${i} failed, ${rc}"
16780         fi
16781
16782         new_count=$(do_facet ost1 \
16783                 $LCTL get_param -n ost.OSS.ost.stats)
16784         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
16785                    awk '{ print $2 }')
16786
16787         difference="$((new_count - count))"
16788         if [ $difference -ne $rc ]; then
16789                 error "Ladvise test${i}, bad enqueue count, returned " \
16790                       "${rc}, actual ${difference}"
16791         fi
16792
16793         for i in $(seq 12 21); do
16794                 # If we do not do this, we run the risk of having too many
16795                 # locks and starting lock cancellation while we are checking
16796                 # lock counts.
16797                 cancel_lru_locks osc
16798
16799                 count=$($LCTL get_param -n \
16800                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16801
16802                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
16803                 rc=$?
16804                 if [ $rc -eq 255 ]; then
16805                         error "Ladvise test ${i} failed, ${rc}"
16806                 fi
16807
16808                 new_count=$($LCTL get_param -n \
16809                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16810                 difference="$((new_count - count))"
16811
16812                 # Test 15 output is divided by 100 to map down to valid return
16813                 if [ $i -eq 15 ]; then
16814                         rc="$((rc * 100))"
16815                 fi
16816
16817                 if [ $difference -ne $rc ]; then
16818                         error "Ladvise test ${i}, bad lock count, returned " \
16819                               "${rc}, actual ${difference}"
16820                 fi
16821         done
16822
16823         #test 22 returns only success/failure
16824         i=22
16825         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16826         rc=$?
16827         if [ $rc -eq 255 ]; then
16828                 error "Ladvise test${i} failed, ${rc}"
16829         fi
16830 }
16831 run_test 255c "suite of ladvise lockahead tests"
16832
16833 test_256() {
16834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16835         remote_mds_nodsh && skip "remote MDS with nodsh"
16836         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
16837         changelog_users $SINGLEMDS | grep "^cl" &&
16838                 skip "active changelog user"
16839
16840         local cl_user
16841         local cat_sl
16842         local mdt_dev
16843
16844         mdt_dev=$(mdsdevname 1)
16845         echo $mdt_dev
16846
16847         changelog_register || error "changelog_register failed"
16848
16849         rm -rf $DIR/$tdir
16850         mkdir -p $DIR/$tdir
16851
16852         changelog_clear 0 || error "changelog_clear failed"
16853
16854         # change something
16855         touch $DIR/$tdir/{1..10}
16856
16857         # stop the MDT
16858         stop $SINGLEMDS || error "Fail to stop MDT"
16859
16860         # remount the MDT
16861
16862         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
16863
16864         #after mount new plainllog is used
16865         touch $DIR/$tdir/{11..19}
16866         local tmpfile=$(mktemp -u $tfile.XXXXXX)
16867         cat_sl=$(do_facet $SINGLEMDS "sync; \
16868                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16869                  llog_reader $tmpfile | grep -c type=1064553b")
16870         do_facet $SINGLEMDS llog_reader $tmpfile
16871
16872         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
16873
16874         changelog_clear 0 || error "changelog_clear failed"
16875
16876         cat_sl=$(do_facet $SINGLEMDS "sync; \
16877                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16878                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
16879
16880         if (( cat_sl == 2 )); then
16881                 error "Empty plain llog was not deleted from changelog catalog"
16882         elif (( cat_sl != 1 )); then
16883                 error "Active plain llog shouldn't be deleted from catalog"
16884         fi
16885 }
16886 run_test 256 "Check llog delete for empty and not full state"
16887
16888 test_257() {
16889         remote_mds_nodsh && skip "remote MDS with nodsh"
16890         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
16891                 skip "Need MDS version at least 2.8.55"
16892
16893         test_mkdir $DIR/$tdir
16894
16895         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
16896                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
16897         stat $DIR/$tdir
16898
16899 #define OBD_FAIL_MDS_XATTR_REP                  0x161
16900         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
16901         local facet=mds$((mdtidx + 1))
16902         set_nodes_failloc $(facet_active_host $facet) 0x80000161
16903         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
16904
16905         stop $facet || error "stop MDS failed"
16906         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
16907                 error "start MDS fail"
16908         wait_recovery_complete $facet
16909 }
16910 run_test 257 "xattr locks are not lost"
16911
16912 # Verify we take the i_mutex when security requires it
16913 test_258a() {
16914 #define OBD_FAIL_IMUTEX_SEC 0x141c
16915         $LCTL set_param fail_loc=0x141c
16916         touch $DIR/$tfile
16917         chmod u+s $DIR/$tfile
16918         chmod a+rwx $DIR/$tfile
16919         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
16920         RC=$?
16921         if [ $RC -ne 0 ]; then
16922                 error "error, failed to take i_mutex, rc=$?"
16923         fi
16924         rm -f $DIR/$tfile
16925 }
16926 run_test 258a
16927
16928 # Verify we do NOT take the i_mutex in the normal case
16929 test_258b() {
16930 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
16931         $LCTL set_param fail_loc=0x141d
16932         touch $DIR/$tfile
16933         chmod a+rwx $DIR
16934         chmod a+rw $DIR/$tfile
16935         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
16936         RC=$?
16937         if [ $RC -ne 0 ]; then
16938                 error "error, took i_mutex unnecessarily, rc=$?"
16939         fi
16940         rm -f $DIR/$tfile
16941
16942 }
16943 run_test 258b "verify i_mutex security behavior"
16944
16945 test_259() {
16946         local file=$DIR/$tfile
16947         local before
16948         local after
16949
16950         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
16951
16952         stack_trap "rm -f $file" EXIT
16953
16954         wait_delete_completed
16955         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
16956         echo "before: $before"
16957
16958         $LFS setstripe -i 0 -c 1 $file
16959         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
16960         sync_all_data
16961         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
16962         echo "after write: $after"
16963
16964 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
16965         do_facet ost1 $LCTL set_param fail_loc=0x2301
16966         $TRUNCATE $file 0
16967         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
16968         echo "after truncate: $after"
16969
16970         stop ost1
16971         do_facet ost1 $LCTL set_param fail_loc=0
16972         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16973         sleep 2
16974         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
16975         echo "after restart: $after"
16976         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
16977                 error "missing truncate?"
16978
16979         return 0
16980 }
16981 run_test 259 "crash at delayed truncate"
16982
16983 test_260() {
16984 #define OBD_FAIL_MDC_CLOSE               0x806
16985         $LCTL set_param fail_loc=0x80000806
16986         touch $DIR/$tfile
16987
16988 }
16989 run_test 260 "Check mdc_close fail"
16990
16991 ### Data-on-MDT sanity tests ###
16992 test_270a() {
16993         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
16994                 skip "Need MDS version at least 2.10.55 for DoM"
16995
16996         # create DoM file
16997         local dom=$DIR/$tdir/dom_file
16998         local tmp=$DIR/$tdir/tmp_file
16999
17000         mkdir -p $DIR/$tdir
17001
17002         # basic checks for DoM component creation
17003         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17004                 error "Can set MDT layout to non-first entry"
17005
17006         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17007                 error "Can define multiple entries as MDT layout"
17008
17009         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17010
17011         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17012         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17013         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17014
17015         local mdtidx=$($LFS getstripe -m $dom)
17016         local mdtname=MDT$(printf %04x $mdtidx)
17017         local facet=mds$((mdtidx + 1))
17018         local space_check=1
17019
17020         # Skip free space checks with ZFS
17021         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17022
17023         # write
17024         sync
17025         local size_tmp=$((65536 * 3))
17026         local mdtfree1=$(do_facet $facet \
17027                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17028
17029         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17030         # check also direct IO along write
17031         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17032         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17033         sync
17034         cmp $tmp $dom || error "file data is different"
17035         [ $(stat -c%s $dom) == $size_tmp ] ||
17036                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17037         if [ $space_check == 1 ]; then
17038                 local mdtfree2=$(do_facet $facet \
17039                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17040
17041                 # increase in usage from by $size_tmp
17042                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17043                         error "MDT free space wrong after write: " \
17044                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17045         fi
17046
17047         # truncate
17048         local size_dom=10000
17049
17050         $TRUNCATE $dom $size_dom
17051         [ $(stat -c%s $dom) == $size_dom ] ||
17052                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17053         if [ $space_check == 1 ]; then
17054                 mdtfree1=$(do_facet $facet \
17055                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17056                 # decrease in usage from $size_tmp to new $size_dom
17057                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17058                   $(((size_tmp - size_dom) / 1024)) ] ||
17059                         error "MDT free space is wrong after truncate: " \
17060                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17061         fi
17062
17063         # append
17064         cat $tmp >> $dom
17065         sync
17066         size_dom=$((size_dom + size_tmp))
17067         [ $(stat -c%s $dom) == $size_dom ] ||
17068                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17069         if [ $space_check == 1 ]; then
17070                 mdtfree2=$(do_facet $facet \
17071                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17072                 # increase in usage by $size_tmp from previous
17073                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17074                         error "MDT free space is wrong after append: " \
17075                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17076         fi
17077
17078         # delete
17079         rm $dom
17080         if [ $space_check == 1 ]; then
17081                 mdtfree1=$(do_facet $facet \
17082                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17083                 # decrease in usage by $size_dom from previous
17084                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17085                         error "MDT free space is wrong after removal: " \
17086                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17087         fi
17088
17089         # combined striping
17090         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17091                 error "Can't create DoM + OST striping"
17092
17093         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17094         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17095         # check also direct IO along write
17096         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17097         sync
17098         cmp $tmp $dom || error "file data is different"
17099         [ $(stat -c%s $dom) == $size_tmp ] ||
17100                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17101         rm $dom $tmp
17102
17103         return 0
17104 }
17105 run_test 270a "DoM: basic functionality tests"
17106
17107 test_270b() {
17108         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17109                 skip "Need MDS version at least 2.10.55"
17110
17111         local dom=$DIR/$tdir/dom_file
17112         local max_size=1048576
17113
17114         mkdir -p $DIR/$tdir
17115         $LFS setstripe -E $max_size -L mdt $dom
17116
17117         # truncate over the limit
17118         $TRUNCATE $dom $(($max_size + 1)) &&
17119                 error "successful truncate over the maximum size"
17120         # write over the limit
17121         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17122                 error "successful write over the maximum size"
17123         # append over the limit
17124         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17125         echo "12345" >> $dom && error "successful append over the maximum size"
17126         rm $dom
17127
17128         return 0
17129 }
17130 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17131
17132 test_270c() {
17133         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17134                 skip "Need MDS version at least 2.10.55"
17135
17136         mkdir -p $DIR/$tdir
17137         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17138
17139         # check files inherit DoM EA
17140         touch $DIR/$tdir/first
17141         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17142                 error "bad pattern"
17143         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17144                 error "bad stripe count"
17145         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17146                 error "bad stripe size"
17147
17148         # check directory inherits DoM EA and uses it as default
17149         mkdir $DIR/$tdir/subdir
17150         touch $DIR/$tdir/subdir/second
17151         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17152                 error "bad pattern in sub-directory"
17153         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17154                 error "bad stripe count in sub-directory"
17155         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17156                 error "bad stripe size in sub-directory"
17157         return 0
17158 }
17159 run_test 270c "DoM: DoM EA inheritance tests"
17160
17161 test_270d() {
17162         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17163                 skip "Need MDS version at least 2.10.55"
17164
17165         mkdir -p $DIR/$tdir
17166         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17167
17168         # inherit default DoM striping
17169         mkdir $DIR/$tdir/subdir
17170         touch $DIR/$tdir/subdir/f1
17171
17172         # change default directory striping
17173         $LFS setstripe -c 1 $DIR/$tdir/subdir
17174         touch $DIR/$tdir/subdir/f2
17175         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17176                 error "wrong default striping in file 2"
17177         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17178                 error "bad pattern in file 2"
17179         return 0
17180 }
17181 run_test 270d "DoM: change striping from DoM to RAID0"
17182
17183 test_270e() {
17184         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17185                 skip "Need MDS version at least 2.10.55"
17186
17187         mkdir -p $DIR/$tdir/dom
17188         mkdir -p $DIR/$tdir/norm
17189         DOMFILES=20
17190         NORMFILES=10
17191         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17192         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17193
17194         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17195         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17196
17197         # find DoM files by layout
17198         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17199         [ $NUM -eq  $DOMFILES ] ||
17200                 error "lfs find -L: found $NUM, expected $DOMFILES"
17201         echo "Test 1: lfs find 20 DOM files by layout: OK"
17202
17203         # there should be 1 dir with default DOM striping
17204         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17205         [ $NUM -eq  1 ] ||
17206                 error "lfs find -L: found $NUM, expected 1 dir"
17207         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17208
17209         # find DoM files by stripe size
17210         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17211         [ $NUM -eq  $DOMFILES ] ||
17212                 error "lfs find -S: found $NUM, expected $DOMFILES"
17213         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17214
17215         # find files by stripe offset except DoM files
17216         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17217         [ $NUM -eq  $NORMFILES ] ||
17218                 error "lfs find -i: found $NUM, expected $NORMFILES"
17219         echo "Test 5: lfs find no DOM files by stripe index: OK"
17220         return 0
17221 }
17222 run_test 270e "DoM: lfs find with DoM files test"
17223
17224 test_270f() {
17225         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17226                 skip "Need MDS version at least 2.10.55"
17227
17228         local mdtname=${FSNAME}-MDT0000-mdtlov
17229         local dom=$DIR/$tdir/dom_file
17230         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17231                                                 lod.$mdtname.dom_stripesize)
17232         local dom_limit=131072
17233
17234         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17235         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17236                                                 lod.$mdtname.dom_stripesize)
17237         [ ${dom_limit} -eq ${dom_current} ] ||
17238                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17239
17240         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17241         $LFS setstripe -d $DIR/$tdir
17242         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17243                 error "Can't set directory default striping"
17244
17245         # exceed maximum stripe size
17246         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17247                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17248         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17249                 error "Able to create DoM component size more than LOD limit"
17250
17251         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17252         dom_current=$(do_facet mds1 $LCTL get_param -n \
17253                                                 lod.$mdtname.dom_stripesize)
17254         [ 0 -eq ${dom_current} ] ||
17255                 error "Can't set zero DoM stripe limit"
17256         rm $dom
17257
17258         # attempt to create DoM file on server with disabled DoM should
17259         # remove DoM entry from layout and be succeed
17260         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17261                 error "Can't create DoM file (DoM is disabled)"
17262         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17263                 error "File has DoM component while DoM is disabled"
17264         rm $dom
17265
17266         # attempt to create DoM file with only DoM stripe should return error
17267         $LFS setstripe -E $dom_limit -L mdt $dom &&
17268                 error "Able to create DoM-only file while DoM is disabled"
17269
17270         # too low values to be aligned with smallest stripe size 64K
17271         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17272         dom_current=$(do_facet mds1 $LCTL get_param -n \
17273                                                 lod.$mdtname.dom_stripesize)
17274         [ 30000 -eq ${dom_current} ] &&
17275                 error "Can set too small DoM stripe limit"
17276
17277         # 64K is a minimal stripe size in Lustre, expect limit of that size
17278         [ 65536 -eq ${dom_current} ] ||
17279                 error "Limit is not set to 64K but ${dom_current}"
17280
17281         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17282         dom_current=$(do_facet mds1 $LCTL get_param -n \
17283                                                 lod.$mdtname.dom_stripesize)
17284         echo $dom_current
17285         [ 2147483648 -eq ${dom_current} ] &&
17286                 error "Can set too large DoM stripe limit"
17287
17288         do_facet mds1 $LCTL set_param -n \
17289                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17290         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17291                 error "Can't create DoM component size after limit change"
17292         do_facet mds1 $LCTL set_param -n \
17293                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17294         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17295                 error "Can't create DoM file after limit decrease"
17296         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17297                 error "Can create big DoM component after limit decrease"
17298         touch ${dom}_def ||
17299                 error "Can't create file with old default layout"
17300
17301         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17302         return 0
17303 }
17304 run_test 270f "DoM: maximum DoM stripe size checks"
17305
17306 test_271a() {
17307         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17308                 skip "Need MDS version at least 2.10.55"
17309
17310         local dom=$DIR/$tdir/dom
17311
17312         mkdir -p $DIR/$tdir
17313
17314         $LFS setstripe -E 1024K -L mdt $dom
17315
17316         lctl set_param -n mdc.*.stats=clear
17317         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17318         cat $dom > /dev/null
17319         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17320         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17321         ls $dom
17322         rm -f $dom
17323 }
17324 run_test 271a "DoM: data is cached for read after write"
17325
17326 test_271b() {
17327         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17328                 skip "Need MDS version at least 2.10.55"
17329
17330         local dom=$DIR/$tdir/dom
17331
17332         mkdir -p $DIR/$tdir
17333
17334         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17335
17336         lctl set_param -n mdc.*.stats=clear
17337         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17338         cancel_lru_locks mdc
17339         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17340         # second stat to check size is cached on client
17341         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17342         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17343         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17344         rm -f $dom
17345 }
17346 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17347
17348 test_271ba() {
17349         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17350                 skip "Need MDS version at least 2.10.55"
17351
17352         local dom=$DIR/$tdir/dom
17353
17354         mkdir -p $DIR/$tdir
17355
17356         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17357
17358         lctl set_param -n mdc.*.stats=clear
17359         lctl set_param -n osc.*.stats=clear
17360         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17361         cancel_lru_locks mdc
17362         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17363         # second stat to check size is cached on client
17364         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17365         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17366         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17367         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17368         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17369         rm -f $dom
17370 }
17371 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17372
17373
17374 get_mdc_stats() {
17375         local mdtidx=$1
17376         local param=$2
17377         local mdt=MDT$(printf %04x $mdtidx)
17378
17379         if [ -z $param ]; then
17380                 lctl get_param -n mdc.*$mdt*.stats
17381         else
17382                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17383         fi
17384 }
17385
17386 test_271c() {
17387         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17388                 skip "Need MDS version at least 2.10.55"
17389
17390         local dom=$DIR/$tdir/dom
17391
17392         mkdir -p $DIR/$tdir
17393
17394         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17395
17396         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17397         local facet=mds$((mdtidx + 1))
17398
17399         cancel_lru_locks mdc
17400         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17401         createmany -o $dom 1000
17402         lctl set_param -n mdc.*.stats=clear
17403         smalliomany -w $dom 1000 200
17404         get_mdc_stats $mdtidx
17405         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17406         # Each file has 1 open, 1 IO enqueues, total 2000
17407         # but now we have also +1 getxattr for security.capability, total 3000
17408         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17409         unlinkmany $dom 1000
17410
17411         cancel_lru_locks mdc
17412         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17413         createmany -o $dom 1000
17414         lctl set_param -n mdc.*.stats=clear
17415         smalliomany -w $dom 1000 200
17416         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17417         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17418         # for OPEN and IO lock.
17419         [ $((enq - enq_2)) -ge 1000 ] ||
17420                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17421         unlinkmany $dom 1000
17422         return 0
17423 }
17424 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17425
17426 cleanup_271def_tests() {
17427         trap 0
17428         rm -f $1
17429 }
17430
17431 test_271d() {
17432         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17433                 skip "Need MDS version at least 2.10.57"
17434
17435         local dom=$DIR/$tdir/dom
17436         local tmp=$TMP/$tfile
17437         trap "cleanup_271def_tests $tmp" EXIT
17438
17439         mkdir -p $DIR/$tdir
17440
17441         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17442
17443         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17444
17445         cancel_lru_locks mdc
17446         dd if=/dev/urandom of=$tmp bs=1000 count=1
17447         dd if=$tmp of=$dom bs=1000 count=1
17448         cancel_lru_locks mdc
17449
17450         cat /etc/hosts >> $tmp
17451         lctl set_param -n mdc.*.stats=clear
17452
17453         # append data to the same file it should update local page
17454         echo "Append to the same page"
17455         cat /etc/hosts >> $dom
17456         local num=$(get_mdc_stats $mdtidx ost_read)
17457         local ra=$(get_mdc_stats $mdtidx req_active)
17458         local rw=$(get_mdc_stats $mdtidx req_waittime)
17459
17460         [ -z $num ] || error "$num READ RPC occured"
17461         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17462         echo "... DONE"
17463
17464         # compare content
17465         cmp $tmp $dom || error "file miscompare"
17466
17467         cancel_lru_locks mdc
17468         lctl set_param -n mdc.*.stats=clear
17469
17470         echo "Open and read file"
17471         cat $dom > /dev/null
17472         local num=$(get_mdc_stats $mdtidx ost_read)
17473         local ra=$(get_mdc_stats $mdtidx req_active)
17474         local rw=$(get_mdc_stats $mdtidx req_waittime)
17475
17476         [ -z $num ] || error "$num READ RPC occured"
17477         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17478         echo "... DONE"
17479
17480         # compare content
17481         cmp $tmp $dom || error "file miscompare"
17482
17483         return 0
17484 }
17485 run_test 271d "DoM: read on open (1K file in reply buffer)"
17486
17487 test_271e() {
17488         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17489                 skip "Need MDS version at least 2.10.57"
17490
17491         local dom=$DIR/$tdir/dom
17492         local tmp=$TMP/${tfile}.data
17493         trap "cleanup_271def_tests $tmp" EXIT
17494
17495         mkdir -p $DIR/$tdir
17496
17497         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17498
17499         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17500
17501         cancel_lru_locks mdc
17502         dd if=/dev/urandom of=$tmp bs=30K count=1
17503         dd if=$tmp of=$dom bs=30K count=1
17504         cancel_lru_locks mdc
17505         cat /etc/hosts >> $tmp
17506         lctl set_param -n mdc.*.stats=clear
17507
17508         echo "Append to the same page"
17509         cat /etc/hosts >> $dom
17510
17511         local num=$(get_mdc_stats $mdtidx ost_read)
17512         local ra=$(get_mdc_stats $mdtidx req_active)
17513         local rw=$(get_mdc_stats $mdtidx req_waittime)
17514
17515         [ -z $num ] || error "$num READ RPC occured"
17516         # Reply buffer can be adjusted for larger buffer by resend
17517         echo "... DONE with $((ra - rw)) resends"
17518
17519         # compare content
17520         cmp $tmp $dom || error "file miscompare"
17521
17522         cancel_lru_locks mdc
17523         lctl set_param -n mdc.*.stats=clear
17524
17525         echo "Open and read file"
17526         cat $dom > /dev/null
17527         local num=$(get_mdc_stats $mdtidx ost_read)
17528         local ra=$(get_mdc_stats $mdtidx req_active)
17529         local rw=$(get_mdc_stats $mdtidx req_waittime)
17530
17531         [ -z $num ] || error "$num READ RPC occured"
17532         # Reply buffer can be adjusted for larger buffer by resend
17533         echo "... DONE with $((ra - rw)) resends"
17534
17535         # compare content
17536         cmp $tmp $dom || error "file miscompare"
17537
17538         return 0
17539 }
17540 run_test 271e "DoM: read on open (30K file with reply buffer adjusting)"
17541
17542 test_271f() {
17543         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17544                 skip "Need MDS version at least 2.10.57"
17545
17546         local dom=$DIR/$tdir/dom
17547         local tmp=$TMP/$tfile
17548         trap "cleanup_271def_tests $tmp" EXIT
17549
17550         mkdir -p $DIR/$tdir
17551
17552         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17553
17554         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17555
17556         cancel_lru_locks mdc
17557         dd if=/dev/urandom of=$tmp bs=200000 count=1
17558         dd if=$tmp of=$dom bs=200000 count=1
17559         cancel_lru_locks mdc
17560         cat /etc/hosts >> $tmp
17561         lctl set_param -n mdc.*.stats=clear
17562
17563         echo "Append to the same page"
17564         cat /etc/hosts >> $dom
17565         local num=$(get_mdc_stats $mdtidx ost_read)
17566         local ra=$(get_mdc_stats $mdtidx req_active)
17567         local rw=$(get_mdc_stats $mdtidx req_waittime)
17568
17569         [ -z $num ] || error "$num READ RPC occured"
17570         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17571         echo "... DONE"
17572
17573         # compare content
17574         cmp $tmp $dom || error "file miscompare"
17575
17576         cancel_lru_locks mdc
17577         lctl set_param -n mdc.*.stats=clear
17578
17579         echo "Open and read file"
17580         cat $dom > /dev/null
17581         local num=$(get_mdc_stats $mdtidx ost_read)
17582         local ra=$(get_mdc_stats $mdtidx req_active)
17583         local rw=$(get_mdc_stats $mdtidx req_waittime)
17584
17585         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
17586         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17587         echo "... DONE"
17588
17589         # compare content
17590         cmp $tmp $dom || error "file miscompare"
17591
17592         return 0
17593 }
17594 run_test 271f "DoM: read on open (200K file and read tail)"
17595
17596 test_272a() {
17597         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17598                 skip "Need MDS version at least 2.11.50"
17599
17600         local dom=$DIR/$tdir/dom
17601         mkdir -p $DIR/$tdir
17602
17603         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
17604         dd if=/dev/urandom of=$dom bs=512K count=1 ||
17605                 error "failed to write data into $dom"
17606         local old_md5=$(md5sum $dom)
17607
17608         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
17609                 error "failed to migrate to the same DoM component"
17610
17611         local new_md5=$(md5sum $dom)
17612
17613         [ "$old_md5" == "$new_md5" ] ||
17614                 error "md5sum differ: $old_md5, $new_md5"
17615
17616         [ $($LFS getstripe -c $dom) -eq 2 ] ||
17617                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
17618 }
17619 run_test 272a "DoM migration: new layout with the same DOM component"
17620
17621 test_272b() {
17622         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17623                 skip "Need MDS version at least 2.11.50"
17624
17625         local dom=$DIR/$tdir/dom
17626         mkdir -p $DIR/$tdir
17627         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17628
17629         local mdtidx=$($LFS getstripe -m $dom)
17630         local mdtname=MDT$(printf %04x $mdtidx)
17631         local facet=mds$((mdtidx + 1))
17632
17633         local mdtfree1=$(do_facet $facet \
17634                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17635         dd if=/dev/urandom of=$dom bs=2M count=1 ||
17636                 error "failed to write data into $dom"
17637         local old_md5=$(md5sum $dom)
17638         cancel_lru_locks mdc
17639         local mdtfree1=$(do_facet $facet \
17640                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17641
17642         $LFS migrate -c2 $dom ||
17643                 error "failed to migrate to the new composite layout"
17644         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17645                 error "MDT stripe was not removed"
17646
17647         cancel_lru_locks mdc
17648         local new_md5=$(md5sum $dom)
17649         [ "$old_md5" != "$new_md5" ] &&
17650                 error "$old_md5 != $new_md5"
17651
17652         # Skip free space checks with ZFS
17653         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17654                 local mdtfree2=$(do_facet $facet \
17655                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17656                 [ $mdtfree2 -gt $mdtfree1 ] ||
17657                         error "MDT space is not freed after migration"
17658         fi
17659         return 0
17660 }
17661 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
17662
17663 test_272c() {
17664         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17665                 skip "Need MDS version at least 2.11.50"
17666
17667         local dom=$DIR/$tdir/$tfile
17668         mkdir -p $DIR/$tdir
17669         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17670
17671         local mdtidx=$($LFS getstripe -m $dom)
17672         local mdtname=MDT$(printf %04x $mdtidx)
17673         local facet=mds$((mdtidx + 1))
17674
17675         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
17676                 error "failed to write data into $dom"
17677         local old_md5=$(md5sum $dom)
17678         cancel_lru_locks mdc
17679         local mdtfree1=$(do_facet $facet \
17680                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17681
17682         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
17683                 error "failed to migrate to the new composite layout"
17684         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17685                 error "MDT stripe was not removed"
17686
17687         cancel_lru_locks mdc
17688         local new_md5=$(md5sum $dom)
17689         [ "$old_md5" != "$new_md5" ] &&
17690                 error "$old_md5 != $new_md5"
17691
17692         # Skip free space checks with ZFS
17693         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17694                 local mdtfree2=$(do_facet $facet \
17695                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17696                 [ $mdtfree2 -gt $mdtfree1 ] ||
17697                         error "MDS space is not freed after migration"
17698         fi
17699         return 0
17700 }
17701 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
17702
17703 test_273a() {
17704         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17705                 skip "Need MDS version at least 2.11.50"
17706
17707         # Layout swap cannot be done if either file has DOM component,
17708         # this will never be supported, migration should be used instead
17709
17710         local dom=$DIR/$tdir/$tfile
17711         mkdir -p $DIR/$tdir
17712
17713         $LFS setstripe -c2 ${dom}_plain
17714         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
17715         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
17716                 error "can swap layout with DoM component"
17717         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
17718                 error "can swap layout with DoM component"
17719
17720         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
17721         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
17722                 error "can swap layout with DoM component"
17723         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
17724                 error "can swap layout with DoM component"
17725         return 0
17726 }
17727 run_test 273a "DoM: layout swapping should fail with DOM"
17728
17729 test_275() {
17730         remote_ost_nodsh && skip "remote OST with nodsh"
17731         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
17732                 skip "Need OST version >= 2.10.57"
17733
17734         local file=$DIR/$tfile
17735         local oss
17736
17737         oss=$(comma_list $(osts_nodes))
17738
17739         dd if=/dev/urandom of=$file bs=1M count=2 ||
17740                 error "failed to create a file"
17741         cancel_lru_locks osc
17742
17743         #lock 1
17744         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17745                 error "failed to read a file"
17746
17747 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
17748         $LCTL set_param fail_loc=0x8000031f
17749
17750         cancel_lru_locks osc &
17751         sleep 1
17752
17753 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
17754         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
17755         #IO takes another lock, but matches the PENDING one
17756         #and places it to the IO RPC
17757         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17758                 error "failed to read a file with PENDING lock"
17759 }
17760 run_test 275 "Read on a canceled duplicate lock"
17761
17762 test_276() {
17763         remote_ost_nodsh && skip "remote OST with nodsh"
17764         local pid
17765
17766         do_facet ost1 "(while true; do \
17767                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
17768                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
17769         pid=$!
17770
17771         for LOOP in $(seq 20); do
17772                 stop ost1
17773                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
17774         done
17775         kill -9 $pid
17776         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
17777                 rm $TMP/sanity_276_pid"
17778 }
17779 run_test 276 "Race between mount and obd_statfs"
17780
17781 cleanup_test_300() {
17782         trap 0
17783         umask $SAVE_UMASK
17784 }
17785 test_striped_dir() {
17786         local mdt_index=$1
17787         local stripe_count
17788         local stripe_index
17789
17790         mkdir -p $DIR/$tdir
17791
17792         SAVE_UMASK=$(umask)
17793         trap cleanup_test_300 RETURN EXIT
17794
17795         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
17796                                                 $DIR/$tdir/striped_dir ||
17797                 error "set striped dir error"
17798
17799         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
17800         [ "$mode" = "755" ] || error "expect 755 got $mode"
17801
17802         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
17803                 error "getdirstripe failed"
17804         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
17805         if [ "$stripe_count" != "2" ]; then
17806                 error "1:stripe_count is $stripe_count, expect 2"
17807         fi
17808         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
17809         if [ "$stripe_count" != "2" ]; then
17810                 error "2:stripe_count is $stripe_count, expect 2"
17811         fi
17812
17813         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
17814         if [ "$stripe_index" != "$mdt_index" ]; then
17815                 error "stripe_index is $stripe_index, expect $mdt_index"
17816         fi
17817
17818         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17819                 error "nlink error after create striped dir"
17820
17821         mkdir $DIR/$tdir/striped_dir/a
17822         mkdir $DIR/$tdir/striped_dir/b
17823
17824         stat $DIR/$tdir/striped_dir/a ||
17825                 error "create dir under striped dir failed"
17826         stat $DIR/$tdir/striped_dir/b ||
17827                 error "create dir under striped dir failed"
17828
17829         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
17830                 error "nlink error after mkdir"
17831
17832         rmdir $DIR/$tdir/striped_dir/a
17833         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
17834                 error "nlink error after rmdir"
17835
17836         rmdir $DIR/$tdir/striped_dir/b
17837         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17838                 error "nlink error after rmdir"
17839
17840         chattr +i $DIR/$tdir/striped_dir
17841         createmany -o $DIR/$tdir/striped_dir/f 10 &&
17842                 error "immutable flags not working under striped dir!"
17843         chattr -i $DIR/$tdir/striped_dir
17844
17845         rmdir $DIR/$tdir/striped_dir ||
17846                 error "rmdir striped dir error"
17847
17848         cleanup_test_300
17849
17850         true
17851 }
17852
17853 test_300a() {
17854         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17855                 skip "skipped for lustre < 2.7.0"
17856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17857         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17858
17859         test_striped_dir 0 || error "failed on striped dir on MDT0"
17860         test_striped_dir 1 || error "failed on striped dir on MDT0"
17861 }
17862 run_test 300a "basic striped dir sanity test"
17863
17864 test_300b() {
17865         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17866                 skip "skipped for lustre < 2.7.0"
17867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17868         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17869
17870         local i
17871         local mtime1
17872         local mtime2
17873         local mtime3
17874
17875         test_mkdir $DIR/$tdir || error "mkdir fail"
17876         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17877                 error "set striped dir error"
17878         for i in {0..9}; do
17879                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
17880                 sleep 1
17881                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
17882                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
17883                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
17884                 sleep 1
17885                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
17886                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
17887                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
17888         done
17889         true
17890 }
17891 run_test 300b "check ctime/mtime for striped dir"
17892
17893 test_300c() {
17894         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17895                 skip "skipped for lustre < 2.7.0"
17896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17897         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17898
17899         local file_count
17900
17901         mkdir -p $DIR/$tdir
17902         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
17903                 error "set striped dir error"
17904
17905         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
17906                 error "chown striped dir failed"
17907
17908         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
17909                 error "create 5k files failed"
17910
17911         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
17912
17913         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
17914
17915         rm -rf $DIR/$tdir
17916 }
17917 run_test 300c "chown && check ls under striped directory"
17918
17919 test_300d() {
17920         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17921                 skip "skipped for lustre < 2.7.0"
17922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17923         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17924
17925         local stripe_count
17926         local file
17927
17928         mkdir -p $DIR/$tdir
17929         $LFS setstripe -c 2 $DIR/$tdir
17930
17931         #local striped directory
17932         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17933                 error "set striped dir error"
17934         createmany -o $DIR/$tdir/striped_dir/f 10 ||
17935                 error "create 10 files failed"
17936
17937         #remote striped directory
17938         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
17939                 error "set striped dir error"
17940         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
17941                 error "create 10 files failed"
17942
17943         for file in $(find $DIR/$tdir); do
17944                 stripe_count=$($LFS getstripe -c $file)
17945                 [ $stripe_count -eq 2 ] ||
17946                         error "wrong stripe $stripe_count for $file"
17947         done
17948
17949         rm -rf $DIR/$tdir
17950 }
17951 run_test 300d "check default stripe under striped directory"
17952
17953 test_300e() {
17954         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
17955                 skip "Need MDS version at least 2.7.55"
17956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17957         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17958
17959         local stripe_count
17960         local file
17961
17962         mkdir -p $DIR/$tdir
17963
17964         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17965                 error "set striped dir error"
17966
17967         touch $DIR/$tdir/striped_dir/a
17968         touch $DIR/$tdir/striped_dir/b
17969         touch $DIR/$tdir/striped_dir/c
17970
17971         mkdir $DIR/$tdir/striped_dir/dir_a
17972         mkdir $DIR/$tdir/striped_dir/dir_b
17973         mkdir $DIR/$tdir/striped_dir/dir_c
17974
17975         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
17976                 error "set striped adir under striped dir error"
17977
17978         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
17979                 error "set striped bdir under striped dir error"
17980
17981         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
17982                 error "set striped cdir under striped dir error"
17983
17984         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
17985                 error "rename dir under striped dir fails"
17986
17987         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
17988                 error "rename dir under different stripes fails"
17989
17990         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
17991                 error "rename file under striped dir should succeed"
17992
17993         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
17994                 error "rename dir under striped dir should succeed"
17995
17996         rm -rf $DIR/$tdir
17997 }
17998 run_test 300e "check rename under striped directory"
17999
18000 test_300f() {
18001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18002         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18003         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18004                 skip "Need MDS version at least 2.7.55"
18005
18006         local stripe_count
18007         local file
18008
18009         rm -rf $DIR/$tdir
18010         mkdir -p $DIR/$tdir
18011
18012         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18013                 error "set striped dir error"
18014
18015         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18016                 error "set striped dir error"
18017
18018         touch $DIR/$tdir/striped_dir/a
18019         mkdir $DIR/$tdir/striped_dir/dir_a
18020         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18021                 error "create striped dir under striped dir fails"
18022
18023         touch $DIR/$tdir/striped_dir1/b
18024         mkdir $DIR/$tdir/striped_dir1/dir_b
18025         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18026                 error "create striped dir under striped dir fails"
18027
18028         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18029                 error "rename dir under different striped dir should fail"
18030
18031         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18032                 error "rename striped dir under diff striped dir should fail"
18033
18034         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18035                 error "rename file under diff striped dirs fails"
18036
18037         rm -rf $DIR/$tdir
18038 }
18039 run_test 300f "check rename cross striped directory"
18040
18041 test_300_check_default_striped_dir()
18042 {
18043         local dirname=$1
18044         local default_count=$2
18045         local default_index=$3
18046         local stripe_count
18047         local stripe_index
18048         local dir_stripe_index
18049         local dir
18050
18051         echo "checking $dirname $default_count $default_index"
18052         $LFS setdirstripe -D -c $default_count -i $default_index \
18053                                 -t all_char $DIR/$tdir/$dirname ||
18054                 error "set default stripe on striped dir error"
18055         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18056         [ $stripe_count -eq $default_count ] ||
18057                 error "expect $default_count get $stripe_count for $dirname"
18058
18059         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18060         [ $stripe_index -eq $default_index ] ||
18061                 error "expect $default_index get $stripe_index for $dirname"
18062
18063         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18064                                                 error "create dirs failed"
18065
18066         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18067         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18068         for dir in $(find $DIR/$tdir/$dirname/*); do
18069                 stripe_count=$($LFS getdirstripe -c $dir)
18070                 [ $stripe_count -eq $default_count ] ||
18071                 [ $stripe_count -eq 0 -o $default_count -eq 1 ] ||
18072                 error "stripe count $default_count != $stripe_count for $dir"
18073
18074                 stripe_index=$($LFS getdirstripe -i $dir)
18075                 [ $default_index -eq -1 -o $stripe_index -eq $default_index ] ||
18076                         error "$stripe_index != $default_index for $dir"
18077
18078                 #check default stripe
18079                 stripe_count=$($LFS getdirstripe -D -c $dir)
18080                 [ $stripe_count -eq $default_count ] ||
18081                 error "default count $default_count != $stripe_count for $dir"
18082
18083                 stripe_index=$($LFS getdirstripe -D -i $dir)
18084                 [ $stripe_index -eq $default_index ] ||
18085                 error "default index $default_index != $stripe_index for $dir"
18086         done
18087         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18088 }
18089
18090 test_300g() {
18091         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18092         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18093                 skip "Need MDS version at least 2.7.55"
18094
18095         local dir
18096         local stripe_count
18097         local stripe_index
18098
18099         mkdir $DIR/$tdir
18100         mkdir $DIR/$tdir/normal_dir
18101
18102         #Checking when client cache stripe index
18103         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18104         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18105                 error "create striped_dir failed"
18106
18107         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18108                 error "create dir0 fails"
18109         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18110         [ $stripe_index -eq 0 ] ||
18111                 error "dir0 expect index 0 got $stripe_index"
18112
18113         mkdir $DIR/$tdir/striped_dir/dir1 ||
18114                 error "create dir1 fails"
18115         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18116         [ $stripe_index -eq 1 ] ||
18117                 error "dir1 expect index 1 got $stripe_index"
18118
18119         #check default stripe count/stripe index
18120         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18121         test_300_check_default_striped_dir normal_dir 1 0
18122         test_300_check_default_striped_dir normal_dir 2 1
18123         test_300_check_default_striped_dir normal_dir 2 -1
18124
18125         #delete default stripe information
18126         echo "delete default stripeEA"
18127         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18128                 error "set default stripe on striped dir error"
18129
18130         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18131         for dir in $(find $DIR/$tdir/normal_dir/*); do
18132                 stripe_count=$($LFS getdirstripe -c $dir)
18133                 [ $stripe_count -eq 0 ] ||
18134                         error "expect 1 get $stripe_count for $dir"
18135                 stripe_index=$($LFS getdirstripe -i $dir)
18136                 [ $stripe_index -eq 0 ] ||
18137                         error "expect 0 get $stripe_index for $dir"
18138         done
18139 }
18140 run_test 300g "check default striped directory for normal directory"
18141
18142 test_300h() {
18143         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18144         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18145                 skip "Need MDS version at least 2.7.55"
18146
18147         local dir
18148         local stripe_count
18149
18150         mkdir $DIR/$tdir
18151         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18152                 error "set striped dir error"
18153
18154         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18155         test_300_check_default_striped_dir striped_dir 1 0
18156         test_300_check_default_striped_dir striped_dir 2 1
18157         test_300_check_default_striped_dir striped_dir 2 -1
18158
18159         #delete default stripe information
18160         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18161                 error "set default stripe on striped dir error"
18162
18163         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18164         for dir in $(find $DIR/$tdir/striped_dir/*); do
18165                 stripe_count=$($LFS getdirstripe -c $dir)
18166                 [ $stripe_count -eq 0 ] ||
18167                         error "expect 1 get $stripe_count for $dir"
18168         done
18169 }
18170 run_test 300h "check default striped directory for striped directory"
18171
18172 test_300i() {
18173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18174         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18175         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18176                 skip "Need MDS version at least 2.7.55"
18177
18178         local stripe_count
18179         local file
18180
18181         mkdir $DIR/$tdir
18182
18183         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18184                 error "set striped dir error"
18185
18186         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18187                 error "create files under striped dir failed"
18188
18189         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18190                 error "set striped hashdir error"
18191
18192         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18193                 error "create dir0 under hash dir failed"
18194         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18195                 error "create dir1 under hash dir failed"
18196
18197         # unfortunately, we need to umount to clear dir layout cache for now
18198         # once we fully implement dir layout, we can drop this
18199         umount_client $MOUNT || error "umount failed"
18200         mount_client $MOUNT || error "mount failed"
18201
18202         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18203         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18204         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18205
18206         #set the stripe to be unknown hash type
18207         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18208         $LCTL set_param fail_loc=0x1901
18209         for ((i = 0; i < 10; i++)); do
18210                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18211                         error "stat f-$i failed"
18212                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18213         done
18214
18215         touch $DIR/$tdir/striped_dir/f0 &&
18216                 error "create under striped dir with unknown hash should fail"
18217
18218         $LCTL set_param fail_loc=0
18219
18220         umount_client $MOUNT || error "umount failed"
18221         mount_client $MOUNT || error "mount failed"
18222
18223         return 0
18224 }
18225 run_test 300i "client handle unknown hash type striped directory"
18226
18227 test_300j() {
18228         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18230         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18231                 skip "Need MDS version at least 2.7.55"
18232
18233         local stripe_count
18234         local file
18235
18236         mkdir $DIR/$tdir
18237
18238         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18239         $LCTL set_param fail_loc=0x1702
18240         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18241                 error "set striped dir error"
18242
18243         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18244                 error "create files under striped dir failed"
18245
18246         $LCTL set_param fail_loc=0
18247
18248         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18249
18250         return 0
18251 }
18252 run_test 300j "test large update record"
18253
18254 test_300k() {
18255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18256         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18257         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18258                 skip "Need MDS version at least 2.7.55"
18259
18260         # this test needs a huge transaction
18261         local kb
18262         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18263         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18264
18265         local stripe_count
18266         local file
18267
18268         mkdir $DIR/$tdir
18269
18270         #define OBD_FAIL_LARGE_STRIPE   0x1703
18271         $LCTL set_param fail_loc=0x1703
18272         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18273                 error "set striped dir error"
18274         $LCTL set_param fail_loc=0
18275
18276         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18277                 error "getstripeddir fails"
18278         rm -rf $DIR/$tdir/striped_dir ||
18279                 error "unlink striped dir fails"
18280
18281         return 0
18282 }
18283 run_test 300k "test large striped directory"
18284
18285 test_300l() {
18286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18287         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18288         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18289                 skip "Need MDS version at least 2.7.55"
18290
18291         local stripe_index
18292
18293         test_mkdir -p $DIR/$tdir/striped_dir
18294         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18295                         error "chown $RUNAS_ID failed"
18296         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18297                 error "set default striped dir failed"
18298
18299         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18300         $LCTL set_param fail_loc=0x80000158
18301         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18302
18303         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18304         [ $stripe_index -eq 1 ] ||
18305                 error "expect 1 get $stripe_index for $dir"
18306 }
18307 run_test 300l "non-root user to create dir under striped dir with stale layout"
18308
18309 test_300m() {
18310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18311         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18312         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18313                 skip "Need MDS version at least 2.7.55"
18314
18315         mkdir -p $DIR/$tdir/striped_dir
18316         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18317                 error "set default stripes dir error"
18318
18319         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18320
18321         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18322         [ $stripe_count -eq 0 ] ||
18323                         error "expect 0 get $stripe_count for a"
18324
18325         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18326                 error "set default stripes dir error"
18327
18328         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18329
18330         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18331         [ $stripe_count -eq 0 ] ||
18332                         error "expect 0 get $stripe_count for b"
18333
18334         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18335                 error "set default stripes dir error"
18336
18337         mkdir $DIR/$tdir/striped_dir/c &&
18338                 error "default stripe_index is invalid, mkdir c should fails"
18339
18340         rm -rf $DIR/$tdir || error "rmdir fails"
18341 }
18342 run_test 300m "setstriped directory on single MDT FS"
18343
18344 cleanup_300n() {
18345         local list=$(comma_list $(mdts_nodes))
18346
18347         trap 0
18348         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18349 }
18350
18351 test_300n() {
18352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18353         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18354         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18355                 skip "Need MDS version at least 2.7.55"
18356         remote_mds_nodsh && skip "remote MDS with nodsh"
18357
18358         local stripe_index
18359         local list=$(comma_list $(mdts_nodes))
18360
18361         trap cleanup_300n RETURN EXIT
18362         mkdir -p $DIR/$tdir
18363         chmod 777 $DIR/$tdir
18364         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18365                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18366                 error "create striped dir succeeds with gid=0"
18367
18368         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18369         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18370                 error "create striped dir fails with gid=-1"
18371
18372         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18373         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18374                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18375                 error "set default striped dir succeeds with gid=0"
18376
18377
18378         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18379         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18380                 error "set default striped dir fails with gid=-1"
18381
18382
18383         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18384         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18385                                         error "create test_dir fails"
18386         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18387                                         error "create test_dir1 fails"
18388         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18389                                         error "create test_dir2 fails"
18390         cleanup_300n
18391 }
18392 run_test 300n "non-root user to create dir under striped dir with default EA"
18393
18394 test_300o() {
18395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18396         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18397         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18398                 skip "Need MDS version at least 2.7.55"
18399
18400         local numfree1
18401         local numfree2
18402
18403         mkdir -p $DIR/$tdir
18404
18405         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18406         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18407         if [ $numfree1 -lt 66000 -o $numfree2 -lt 66000 ]; then
18408                 skip "not enough free inodes $numfree1 $numfree2"
18409         fi
18410
18411         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18412         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18413         if [ $numfree1 -lt 300000 -o $numfree2 -lt 300000 ]; then
18414                 skip "not enough free space $numfree1 $numfree2"
18415         fi
18416
18417         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18418                 error "setdirstripe fails"
18419
18420         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18421                 error "create dirs fails"
18422
18423         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18424         ls $DIR/$tdir/striped_dir > /dev/null ||
18425                 error "ls striped dir fails"
18426         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18427                 error "unlink big striped dir fails"
18428 }
18429 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18430
18431 test_300p() {
18432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18433         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18434         remote_mds_nodsh && skip "remote MDS with nodsh"
18435
18436         mkdir -p $DIR/$tdir
18437
18438         #define OBD_FAIL_OUT_ENOSPC     0x1704
18439         do_facet mds2 lctl set_param fail_loc=0x80001704
18440         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18441                  && error "create striped directory should fail"
18442
18443         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18444
18445         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18446         true
18447 }
18448 run_test 300p "create striped directory without space"
18449
18450 test_300q() {
18451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18452         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18453
18454         local fd=$(free_fd)
18455         local cmd="exec $fd<$tdir"
18456         cd $DIR
18457         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18458         eval $cmd
18459         cmd="exec $fd<&-"
18460         trap "eval $cmd" EXIT
18461         cd $tdir || error "cd $tdir fails"
18462         rmdir  ../$tdir || error "rmdir $tdir fails"
18463         mkdir local_dir && error "create dir succeeds"
18464         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
18465         eval $cmd
18466         return 0
18467 }
18468 run_test 300q "create remote directory under orphan directory"
18469
18470 test_300r() {
18471         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
18472                 skip "Need MDS version at least 2.7.55" && return
18473         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18474
18475         mkdir $DIR/$tdir
18476
18477         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
18478                 error "set striped dir error"
18479
18480         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18481                 error "getstripeddir fails"
18482
18483         local stripe_count
18484         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18485                       awk '/lmv_stripe_count:/ { print $2 }')
18486
18487         [ $MDSCOUNT -ne $stripe_count ] &&
18488                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
18489
18490         rm -rf $DIR/$tdir/striped_dir ||
18491                 error "unlink striped dir fails"
18492 }
18493 run_test 300r "test -1 striped directory"
18494
18495 prepare_remote_file() {
18496         mkdir $DIR/$tdir/src_dir ||
18497                 error "create remote source failed"
18498
18499         cp /etc/hosts $DIR/$tdir/src_dir/a ||
18500                  error "cp to remote source failed"
18501         touch $DIR/$tdir/src_dir/a
18502
18503         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
18504                 error "create remote target dir failed"
18505
18506         touch $DIR/$tdir/tgt_dir/b
18507
18508         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
18509                 error "rename dir cross MDT failed!"
18510
18511         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
18512                 error "src_child still exists after rename"
18513
18514         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
18515                 error "missing file(a) after rename"
18516
18517         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
18518                 error "diff after rename"
18519 }
18520
18521 test_310a() {
18522         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18524
18525         local remote_file=$DIR/$tdir/tgt_dir/b
18526
18527         mkdir -p $DIR/$tdir
18528
18529         prepare_remote_file || error "prepare remote file failed"
18530
18531         #open-unlink file
18532         $OPENUNLINK $remote_file $remote_file ||
18533                 error "openunlink $remote_file failed"
18534         $CHECKSTAT -a $remote_file || error "$remote_file exists"
18535 }
18536 run_test 310a "open unlink remote file"
18537
18538 test_310b() {
18539         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18541
18542         local remote_file=$DIR/$tdir/tgt_dir/b
18543
18544         mkdir -p $DIR/$tdir
18545
18546         prepare_remote_file || error "prepare remote file failed"
18547
18548         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18549         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
18550         $CHECKSTAT -t file $remote_file || error "check file failed"
18551 }
18552 run_test 310b "unlink remote file with multiple links while open"
18553
18554 test_310c() {
18555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18556         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
18557
18558         local remote_file=$DIR/$tdir/tgt_dir/b
18559
18560         mkdir -p $DIR/$tdir
18561
18562         prepare_remote_file || error "prepare remote file failed"
18563
18564         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18565         multiop_bg_pause $remote_file O_uc ||
18566                         error "mulitop failed for remote file"
18567         MULTIPID=$!
18568         $MULTIOP $DIR/$tfile Ouc
18569         kill -USR1 $MULTIPID
18570         wait $MULTIPID
18571 }
18572 run_test 310c "open-unlink remote file with multiple links"
18573
18574 #LU-4825
18575 test_311() {
18576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18577         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18578         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
18579                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
18580         remote_mds_nodsh && skip "remote MDS with nodsh"
18581
18582         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18583         local mdts=$(comma_list $(mdts_nodes))
18584
18585         mkdir -p $DIR/$tdir
18586         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18587         createmany -o $DIR/$tdir/$tfile. 1000
18588
18589         # statfs data is not real time, let's just calculate it
18590         old_iused=$((old_iused + 1000))
18591
18592         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18593                         osp.*OST0000*MDT0000.create_count")
18594         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18595                                 osp.*OST0000*MDT0000.max_create_count")
18596         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
18597
18598         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
18599         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
18600         [ $index -ne 0 ] || error "$tfile stripe index is 0"
18601
18602         unlinkmany $DIR/$tdir/$tfile. 1000
18603
18604         do_nodes $mdts "$LCTL set_param -n \
18605                         osp.*OST0000*.max_create_count=$max_count"
18606         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
18607                 do_nodes $mdts "$LCTL set_param -n \
18608                                 osp.*OST0000*.create_count=$count"
18609         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
18610                         grep "=0" && error "create_count is zero"
18611
18612         local new_iused
18613         for i in $(seq 120); do
18614                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18615                 # system may be too busy to destroy all objs in time, use
18616                 # a somewhat small value to not fail autotest
18617                 [ $((old_iused - new_iused)) -gt 400 ] && break
18618                 sleep 1
18619         done
18620
18621         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
18622         [ $((old_iused - new_iused)) -gt 400 ] ||
18623                 error "objs not destroyed after unlink"
18624 }
18625 run_test 311 "disable OSP precreate, and unlink should destroy objs"
18626
18627 zfs_oid_to_objid()
18628 {
18629         local ost=$1
18630         local objid=$2
18631
18632         local vdevdir=$(dirname $(facet_vdevice $ost))
18633         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
18634         local zfs_zapid=$(do_facet $ost $cmd |
18635                           grep -w "/O/0/d$((objid%32))" -C 5 |
18636                           awk '/Object/{getline; print $1}')
18637         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
18638                           awk "/$objid = /"'{printf $3}')
18639
18640         echo $zfs_objid
18641 }
18642
18643 zfs_object_blksz() {
18644         local ost=$1
18645         local objid=$2
18646
18647         local vdevdir=$(dirname $(facet_vdevice $ost))
18648         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
18649         local blksz=$(do_facet $ost $cmd $objid |
18650                       awk '/dblk/{getline; printf $4}')
18651
18652         case "${blksz: -1}" in
18653                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
18654                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
18655                 *) ;;
18656         esac
18657
18658         echo $blksz
18659 }
18660
18661 test_312() { # LU-4856
18662         remote_ost_nodsh && skip "remote OST with nodsh"
18663         [ "$ost1_FSTYPE" = "zfs" ] ||
18664                 skip_env "the test only applies to zfs"
18665
18666         local max_blksz=$(do_facet ost1 \
18667                           $ZFS get -p recordsize $(facet_device ost1) |
18668                           awk '!/VALUE/{print $3}')
18669
18670         # to make life a little bit easier
18671         $LFS mkdir -c 1 -i 0 $DIR/$tdir
18672         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18673
18674         local tf=$DIR/$tdir/$tfile
18675         touch $tf
18676         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18677
18678         # Get ZFS object id
18679         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18680         # block size change by sequential overwrite
18681         local bs
18682
18683         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
18684                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
18685
18686                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
18687                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
18688         done
18689         rm -f $tf
18690
18691         # block size change by sequential append write
18692         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
18693         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18694         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18695         local count
18696
18697         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
18698                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
18699                         oflag=sync conv=notrunc
18700
18701                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
18702                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
18703                         error "blksz error, actual $blksz, " \
18704                                 "expected: 2 * $count * $PAGE_SIZE"
18705         done
18706         rm -f $tf
18707
18708         # random write
18709         touch $tf
18710         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18711         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18712
18713         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
18714         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18715         [ $blksz -eq $PAGE_SIZE ] ||
18716                 error "blksz error: $blksz, expected: $PAGE_SIZE"
18717
18718         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
18719         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18720         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
18721
18722         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
18723         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18724         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
18725 }
18726 run_test 312 "make sure ZFS adjusts its block size by write pattern"
18727
18728 test_313() {
18729         remote_ost_nodsh && skip "remote OST with nodsh"
18730
18731         local file=$DIR/$tfile
18732
18733         rm -f $file
18734         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
18735
18736         # define OBD_FAIL_TGT_RCVD_EIO           0x720
18737         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18738         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
18739                 error "write should failed"
18740         do_facet ost1 "$LCTL set_param fail_loc=0"
18741         rm -f $file
18742 }
18743 run_test 313 "io should fail after last_rcvd update fail"
18744
18745 test_314() {
18746         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18747
18748         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
18749         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18750         rm -f $DIR/$tfile
18751         wait_delete_completed
18752         do_facet ost1 "$LCTL set_param fail_loc=0"
18753 }
18754 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
18755
18756 test_315() { # LU-618
18757         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
18758
18759         local file=$DIR/$tfile
18760         rm -f $file
18761
18762         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
18763                 error "multiop file write failed"
18764         $MULTIOP $file oO_RDONLY:r4063232_c &
18765         PID=$!
18766
18767         sleep 2
18768
18769         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
18770         kill -USR1 $PID
18771
18772         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
18773         rm -f $file
18774 }
18775 run_test 315 "read should be accounted"
18776
18777 test_316() {
18778         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18779         large_xattr_enabled || skip_env "ea_inode feature disabled"
18780
18781         rm -rf $DIR/$tdir/d
18782         mkdir -p $DIR/$tdir/d
18783         chown nobody $DIR/$tdir/d
18784         touch $DIR/$tdir/d/file
18785
18786         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
18787 }
18788 run_test 316 "lfs mv"
18789
18790 test_317() {
18791         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
18792                 skip "Need MDS version at least 2.11.53"
18793         local trunc_sz
18794         local grant_blk_size
18795
18796         if [ "$(facet_fstype $facet)" == "zfs" ]; then
18797                 skip "LU-10370: no implementation for ZFS" && return
18798         fi
18799
18800         stack_trap "rm -f $DIR/$tfile" EXIT
18801         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
18802                         awk '/grant_block_size:/ { print $2; exit; }')
18803         #
18804         # Create File of size 5M. Truncate it to below size's and verify
18805         # blocks count.
18806         #
18807         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
18808                 error "Create file : $DIR/$tfile"
18809
18810         for trunc_sz in 2097152 4097 4000 509 0; do
18811                 $TRUNCATE $DIR/$tfile $trunc_sz ||
18812                         error "truncate $tfile to $trunc_sz failed"
18813                 local sz=$(stat --format=%s $DIR/$tfile)
18814                 local blk=$(stat --format=%b $DIR/$tfile)
18815                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
18816                                      grant_blk_size) * 8))
18817
18818                 if [[ $blk -ne $trunc_blk ]]; then
18819                         $(which stat) $DIR/$tfile
18820                         error "Expected Block $trunc_blk got $blk for $tfile"
18821                 fi
18822
18823                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18824                         error "Expected Size $trunc_sz got $sz for $tfile"
18825         done
18826
18827         #
18828         # sparse file test
18829         # Create file with a hole and write actual two blocks. Block count
18830         # must be 16.
18831         #
18832         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
18833                 conv=fsync || error "Create file : $DIR/$tfile"
18834
18835         # Calculate the final truncate size.
18836         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
18837
18838         #
18839         # truncate to size $trunc_sz bytes. Strip the last block
18840         # The block count must drop to 8
18841         #
18842         $TRUNCATE $DIR/$tfile $trunc_sz ||
18843                 error "truncate $tfile to $trunc_sz failed"
18844
18845         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
18846         sz=$(stat --format=%s $DIR/$tfile)
18847         blk=$(stat --format=%b $DIR/$tfile)
18848
18849         if [[ $blk -ne $trunc_bsz ]]; then
18850                 $(which stat) $DIR/$tfile
18851                 error "Expected Block $trunc_bsz got $blk for $tfile"
18852         fi
18853
18854         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18855                 error "Expected Size $trunc_sz got $sz for $tfile"
18856 }
18857 run_test 317 "Verify blocks get correctly update after truncate"
18858
18859 test_319() {
18860         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
18861
18862         local before=$(date +%s)
18863         local evict
18864         local mdir=$DIR/$tdir
18865         local file=$mdir/xxx
18866
18867         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
18868         touch $file
18869
18870 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
18871         $LCTL set_param fail_val=5 fail_loc=0x8000032c
18872         $LFS mv -m1 $file &
18873
18874         sleep 1
18875         dd if=$file of=/dev/null
18876         wait
18877         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
18878           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
18879
18880         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
18881 }
18882 run_test 319 "lost lease lock on migrate error"
18883
18884 test_fake_rw() {
18885         local read_write=$1
18886         if [ "$read_write" = "write" ]; then
18887                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
18888         elif [ "$read_write" = "read" ]; then
18889                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
18890         else
18891                 error "argument error"
18892         fi
18893
18894         # turn off debug for performance testing
18895         local saved_debug=$($LCTL get_param -n debug)
18896         $LCTL set_param debug=0
18897
18898         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18899
18900         # get ost1 size - lustre-OST0000
18901         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
18902         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
18903         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
18904
18905         if [ "$read_write" = "read" ]; then
18906                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
18907         fi
18908
18909         local start_time=$(date +%s.%N)
18910         $dd_cmd bs=1M count=$blocks oflag=sync ||
18911                 error "real dd $read_write error"
18912         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
18913
18914         if [ "$read_write" = "write" ]; then
18915                 rm -f $DIR/$tfile
18916         fi
18917
18918         # define OBD_FAIL_OST_FAKE_RW           0x238
18919         do_facet ost1 $LCTL set_param fail_loc=0x238
18920
18921         local start_time=$(date +%s.%N)
18922         $dd_cmd bs=1M count=$blocks oflag=sync ||
18923                 error "fake dd $read_write error"
18924         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
18925
18926         if [ "$read_write" = "write" ]; then
18927                 # verify file size
18928                 cancel_lru_locks osc
18929                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
18930                         error "$tfile size not $blocks MB"
18931         fi
18932         do_facet ost1 $LCTL set_param fail_loc=0
18933
18934         echo "fake $read_write $duration_fake vs. normal $read_write" \
18935                 "$duration in seconds"
18936         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
18937                 error_not_in_vm "fake write is slower"
18938
18939         $LCTL set_param -n debug="$saved_debug"
18940         rm -f $DIR/$tfile
18941 }
18942 test_399a() { # LU-7655 for OST fake write
18943         remote_ost_nodsh && skip "remote OST with nodsh"
18944
18945         test_fake_rw write
18946 }
18947 run_test 399a "fake write should not be slower than normal write"
18948
18949 test_399b() { # LU-8726 for OST fake read
18950         remote_ost_nodsh && skip "remote OST with nodsh"
18951         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
18952                 skip_env "ldiskfs only test"
18953         fi
18954
18955         test_fake_rw read
18956 }
18957 run_test 399b "fake read should not be slower than normal read"
18958
18959 test_400a() { # LU-1606, was conf-sanity test_74
18960         if ! which $CC > /dev/null 2>&1; then
18961                 skip_env "$CC is not installed"
18962         fi
18963
18964         local extra_flags=''
18965         local out=$TMP/$tfile
18966         local prefix=/usr/include/lustre
18967         local prog
18968
18969         if ! [[ -d $prefix ]]; then
18970                 # Assume we're running in tree and fixup the include path.
18971                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
18972                 extra_flags+=" -L$LUSTRE/utils/.lib"
18973         fi
18974
18975         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
18976                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
18977                         error "client api broken"
18978         done
18979         rm -f $out
18980 }
18981 run_test 400a "Lustre client api program can compile and link"
18982
18983 test_400b() { # LU-1606, LU-5011
18984         local header
18985         local out=$TMP/$tfile
18986         local prefix=/usr/include/linux/lustre
18987
18988         # We use a hard coded prefix so that this test will not fail
18989         # when run in tree. There are headers in lustre/include/lustre/
18990         # that are not packaged (like lustre_idl.h) and have more
18991         # complicated include dependencies (like config.h and lnet/types.h).
18992         # Since this test about correct packaging we just skip them when
18993         # they don't exist (see below) rather than try to fixup cppflags.
18994
18995         if ! which $CC > /dev/null 2>&1; then
18996                 skip_env "$CC is not installed"
18997         fi
18998
18999         for header in $prefix/*.h; do
19000                 if ! [[ -f "$header" ]]; then
19001                         continue
19002                 fi
19003
19004                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19005                         continue # lustre_ioctl.h is internal header
19006                 fi
19007
19008                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19009                         error "cannot compile '$header'"
19010         done
19011         rm -f $out
19012 }
19013 run_test 400b "packaged headers can be compiled"
19014
19015 test_401a() { #LU-7437
19016         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19017         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19018
19019         #count the number of parameters by "list_param -R"
19020         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19021         #count the number of parameters by listing proc files
19022         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19023         echo "proc_dirs='$proc_dirs'"
19024         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19025         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19026                       sort -u | wc -l)
19027
19028         [ $params -eq $procs ] ||
19029                 error "found $params parameters vs. $procs proc files"
19030
19031         # test the list_param -D option only returns directories
19032         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19033         #count the number of parameters by listing proc directories
19034         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19035                 sort -u | wc -l)
19036
19037         [ $params -eq $procs ] ||
19038                 error "found $params parameters vs. $procs proc files"
19039 }
19040 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19041
19042 test_401b() {
19043         local save=$($LCTL get_param -n jobid_var)
19044         local tmp=testing
19045
19046         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19047                 error "no error returned when setting bad parameters"
19048
19049         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19050         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19051
19052         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19053         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19054         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19055 }
19056 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19057
19058 test_401c() {
19059         local jobid_var_old=$($LCTL get_param -n jobid_var)
19060         local jobid_var_new
19061
19062         $LCTL set_param jobid_var= &&
19063                 error "no error returned for 'set_param a='"
19064
19065         jobid_var_new=$($LCTL get_param -n jobid_var)
19066         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19067                 error "jobid_var was changed by setting without value"
19068
19069         $LCTL set_param jobid_var &&
19070                 error "no error returned for 'set_param a'"
19071
19072         jobid_var_new=$($LCTL get_param -n jobid_var)
19073         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19074                 error "jobid_var was changed by setting without value"
19075 }
19076 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19077
19078 test_401d() {
19079         local jobid_var_old=$($LCTL get_param -n jobid_var)
19080         local jobid_var_new
19081         local new_value="foo=bar"
19082
19083         $LCTL set_param jobid_var=$new_value ||
19084                 error "'set_param a=b' did not accept a value containing '='"
19085
19086         jobid_var_new=$($LCTL get_param -n jobid_var)
19087         [[ "$jobid_var_new" == "$new_value" ]] ||
19088                 error "'set_param a=b' failed on a value containing '='"
19089
19090         # Reset the jobid_var to test the other format
19091         $LCTL set_param jobid_var=$jobid_var_old
19092         jobid_var_new=$($LCTL get_param -n jobid_var)
19093         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19094                 error "failed to reset jobid_var"
19095
19096         $LCTL set_param jobid_var $new_value ||
19097                 error "'set_param a b' did not accept a value containing '='"
19098
19099         jobid_var_new=$($LCTL get_param -n jobid_var)
19100         [[ "$jobid_var_new" == "$new_value" ]] ||
19101                 error "'set_param a b' failed on a value containing '='"
19102
19103         $LCTL set_param jobid_var $jobid_var_old
19104         jobid_var_new=$($LCTL get_param -n jobid_var)
19105         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19106                 error "failed to reset jobid_var"
19107 }
19108 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19109
19110 test_402() {
19111         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19112         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19113                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19114         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19115                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19116                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19117         remote_mds_nodsh && skip "remote MDS with nodsh"
19118
19119         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19120 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19121         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19122         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19123                 echo "Touch failed - OK"
19124 }
19125 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19126
19127 test_403() {
19128         local file1=$DIR/$tfile.1
19129         local file2=$DIR/$tfile.2
19130         local tfile=$TMP/$tfile
19131
19132         rm -f $file1 $file2 $tfile
19133
19134         touch $file1
19135         ln $file1 $file2
19136
19137         # 30 sec OBD_TIMEOUT in ll_getattr()
19138         # right before populating st_nlink
19139         $LCTL set_param fail_loc=0x80001409
19140         stat -c %h $file1 > $tfile &
19141
19142         # create an alias, drop all locks and reclaim the dentry
19143         < $file2
19144         cancel_lru_locks mdc
19145         cancel_lru_locks osc
19146         sysctl -w vm.drop_caches=2
19147
19148         wait
19149
19150         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19151
19152         rm -f $tfile $file1 $file2
19153 }
19154 run_test 403 "i_nlink should not drop to zero due to aliasing"
19155
19156 test_404() { # LU-6601
19157         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19158                 skip "Need server version newer than 2.8.52"
19159         remote_mds_nodsh && skip "remote MDS with nodsh"
19160
19161         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19162                 awk '/osp .*-osc-MDT/ { print $4}')
19163
19164         local osp
19165         for osp in $mosps; do
19166                 echo "Deactivate: " $osp
19167                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19168                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19169                         awk -vp=$osp '$4 == p { print $2 }')
19170                 [ $stat = IN ] || {
19171                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19172                         error "deactivate error"
19173                 }
19174                 echo "Activate: " $osp
19175                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19176                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19177                         awk -vp=$osp '$4 == p { print $2 }')
19178                 [ $stat = UP ] || {
19179                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19180                         error "activate error"
19181                 }
19182         done
19183 }
19184 run_test 404 "validate manual {de}activated works properly for OSPs"
19185
19186 test_405() {
19187         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19188         [ $MDS1_VERSION -lt $(version_code 2.6.92) -o \
19189         [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19190                 skip "Layout swap lock is not supported"
19191         check_swap_layouts_support
19192
19193         test_mkdir $DIR/$tdir
19194         swap_lock_test -d $DIR/$tdir ||
19195                 error "One layout swap locked test failed"
19196 }
19197 run_test 405 "Various layout swap lock tests"
19198
19199 test_406() {
19200         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19201         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19202         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19204         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19205                 skip "Need MDS version at least 2.8.50"
19206
19207         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19208         local test_pool=$TESTNAME
19209
19210         if ! combined_mgs_mds ; then
19211                 mount_mgs_client
19212         fi
19213         pool_add $test_pool || error "pool_add failed"
19214         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19215                 error "pool_add_targets failed"
19216
19217         save_layout_restore_at_exit $MOUNT
19218
19219         # parent set default stripe count only, child will stripe from both
19220         # parent and fs default
19221         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19222                 error "setstripe $MOUNT failed"
19223         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19224         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19225         for i in $(seq 10); do
19226                 local f=$DIR/$tdir/$tfile.$i
19227                 touch $f || error "touch failed"
19228                 local count=$($LFS getstripe -c $f)
19229                 [ $count -eq $OSTCOUNT ] ||
19230                         error "$f stripe count $count != $OSTCOUNT"
19231                 local offset=$($LFS getstripe -i $f)
19232                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19233                 local size=$($LFS getstripe -S $f)
19234                 [ $size -eq $((def_stripe_size * 2)) ] ||
19235                         error "$f stripe size $size != $((def_stripe_size * 2))"
19236                 local pool=$($LFS getstripe -p $f)
19237                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19238         done
19239
19240         # change fs default striping, delete parent default striping, now child
19241         # will stripe from new fs default striping only
19242         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19243                 error "change $MOUNT default stripe failed"
19244         $LFS setstripe -c 0 $DIR/$tdir ||
19245                 error "delete $tdir default stripe failed"
19246         for i in $(seq 11 20); do
19247                 local f=$DIR/$tdir/$tfile.$i
19248                 touch $f || error "touch $f failed"
19249                 local count=$($LFS getstripe -c $f)
19250                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19251                 local offset=$($LFS getstripe -i $f)
19252                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19253                 local size=$($LFS getstripe -S $f)
19254                 [ $size -eq $def_stripe_size ] ||
19255                         error "$f stripe size $size != $def_stripe_size"
19256                 local pool=$($LFS getstripe -p $f)
19257                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19258         done
19259
19260         unlinkmany $DIR/$tdir/$tfile. 1 20
19261
19262         local f=$DIR/$tdir/$tfile
19263         pool_remove_all_targets $test_pool $f
19264         pool_remove $test_pool $f
19265
19266         if ! combined_mgs_mds ; then
19267                 umount_mgs_client
19268         fi
19269 }
19270 run_test 406 "DNE support fs default striping"
19271
19272 test_407() {
19273         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19274         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19275                 skip "Need MDS version at least 2.8.55"
19276         remote_mds_nodsh && skip "remote MDS with nodsh"
19277
19278         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19279                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19280         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19281                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19282         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19283
19284         #define OBD_FAIL_DT_TXN_STOP    0x2019
19285         for idx in $(seq $MDSCOUNT); do
19286                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19287         done
19288         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19289         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19290                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19291         true
19292 }
19293 run_test 407 "transaction fail should cause operation fail"
19294
19295 test_408() {
19296         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19297
19298         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19299         lctl set_param fail_loc=0x8000040a
19300         # let ll_prepare_partial_page() fail
19301         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19302
19303         rm -f $DIR/$tfile
19304
19305         # create at least 100 unused inodes so that
19306         # shrink_icache_memory(0) should not return 0
19307         touch $DIR/$tfile-{0..100}
19308         rm -f $DIR/$tfile-{0..100}
19309         sync
19310
19311         echo 2 > /proc/sys/vm/drop_caches
19312 }
19313 run_test 408 "drop_caches should not hang due to page leaks"
19314
19315 test_409()
19316 {
19317         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19318
19319         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19320         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19321         touch $DIR/$tdir/guard || error "(2) Fail to create"
19322
19323         local PREFIX=$(str_repeat 'A' 128)
19324         echo "Create 1K hard links start at $(date)"
19325         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19326                 error "(3) Fail to hard link"
19327
19328         echo "Links count should be right although linkEA overflow"
19329         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19330         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19331         [ $linkcount -eq 1001 ] ||
19332                 error "(5) Unexpected hard links count: $linkcount"
19333
19334         echo "List all links start at $(date)"
19335         ls -l $DIR/$tdir/foo > /dev/null ||
19336                 error "(6) Fail to list $DIR/$tdir/foo"
19337
19338         echo "Unlink hard links start at $(date)"
19339         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19340                 error "(7) Fail to unlink"
19341         echo "Unlink hard links finished at $(date)"
19342 }
19343 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19344
19345 test_410()
19346 {
19347         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19348                 skip "Need client version at least 2.9.59"
19349
19350         # Create a file, and stat it from the kernel
19351         local testfile=$DIR/$tfile
19352         touch $testfile
19353
19354         local run_id=$RANDOM
19355         local my_ino=$(stat --format "%i" $testfile)
19356
19357         # Try to insert the module. This will always fail as the
19358         # module is designed to not be inserted.
19359         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19360             &> /dev/null
19361
19362         # Anything but success is a test failure
19363         dmesg | grep -q \
19364             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19365             error "no inode match"
19366 }
19367 run_test 410 "Test inode number returned from kernel thread"
19368
19369 cleanup_test411_cgroup() {
19370         trap 0
19371         rmdir "$1"
19372 }
19373
19374 test_411() {
19375         local cg_basedir=/sys/fs/cgroup/memory
19376         # LU-9966
19377         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19378                 skip "no setup for cgroup"
19379
19380         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19381                 error "test file creation failed"
19382         cancel_lru_locks osc
19383
19384         # Create a very small memory cgroup to force a slab allocation error
19385         local cgdir=$cg_basedir/osc_slab_alloc
19386         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19387         trap "cleanup_test411_cgroup $cgdir" EXIT
19388         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19389         echo 1M > $cgdir/memory.limit_in_bytes
19390
19391         # Should not LBUG, just be killed by oom-killer
19392         # dd will return 0 even allocation failure in some environment.
19393         # So don't check return value
19394         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19395         cleanup_test411_cgroup $cgdir
19396
19397         return 0
19398 }
19399 run_test 411 "Slab allocation error with cgroup does not LBUG"
19400
19401 test_412() {
19402         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19403         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19404                 skip "Need server version at least 2.10.55"
19405         fi
19406
19407         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19408                 error "mkdir failed"
19409         $LFS getdirstripe $DIR/$tdir
19410         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19411         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19412                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19413         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19414         [ $stripe_count -eq 2 ] ||
19415                 error "expect 2 get $stripe_count"
19416 }
19417 run_test 412 "mkdir on specific MDTs"
19418
19419 test_413() {
19420         [ $MDSCOUNT -lt 2 ] &&
19421                 skip "We need at least 2 MDTs for this test"
19422
19423         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19424                 skip "Need server version at least 2.10.55"
19425         fi
19426
19427         mkdir $DIR/$tdir || error "mkdir failed"
19428
19429         # find MDT that is the most full
19430         local max=$($LFS df | grep MDT |
19431                 awk 'BEGIN { a=0 }
19432                         { sub("%", "", $5)
19433                           if (0+$5 >= a)
19434                           {
19435                                 a = $5
19436                                 b = $6
19437                           }
19438                         }
19439                      END { split(b, c, ":")
19440                            sub("]", "", c[2])
19441                            print c[2]
19442                          }')
19443
19444         for i in $(seq $((MDSCOUNT - 1))); do
19445                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19446                         error "mkdir d$i failed"
19447                 $LFS getdirstripe $DIR/$tdir/d$i
19448                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19449                 [ $stripe_index -ne $max ] ||
19450                         error "don't expect $max"
19451         done
19452 }
19453 run_test 413 "mkdir on less full MDTs"
19454
19455 test_414() {
19456 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
19457         $LCTL set_param fail_loc=0x80000521
19458         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
19459         rm -f $DIR/$tfile
19460 }
19461 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
19462
19463 test_415() {
19464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19465         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
19466                 skip "Need server version at least 2.11.52"
19467
19468         # LU-11102
19469         local total
19470         local setattr_pid
19471         local start_time
19472         local end_time
19473         local duration
19474
19475         total=500
19476         # this test may be slow on ZFS
19477         [ "$mds1_FSTYPE" == "zfs" ] && total=100
19478
19479         # though this test is designed for striped directory, let's test normal
19480         # directory too since lock is always saved as CoS lock.
19481         test_mkdir $DIR/$tdir || error "mkdir $tdir"
19482         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
19483
19484         (
19485                 while true; do
19486                         touch $DIR/$tdir
19487                 done
19488         ) &
19489         setattr_pid=$!
19490
19491         start_time=$(date +%s)
19492         for i in $(seq $total); do
19493                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
19494                         > /dev/null
19495         done
19496         end_time=$(date +%s)
19497         duration=$((end_time - start_time))
19498
19499         kill -9 $setattr_pid
19500
19501         echo "rename $total files took $duration sec"
19502         [ $duration -lt 100 ] || error "rename took $duration sec"
19503 }
19504 run_test 415 "lock revoke is not missing"
19505
19506 test_416() {
19507         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
19508                 skip "Need server version at least 2.11.55"
19509
19510         # define OBD_FAIL_OSD_TXN_START    0x19a
19511         do_facet mds1 lctl set_param fail_loc=0x19a
19512
19513         lfs mkdir -c $MDSCOUNT $DIR/$tdir
19514
19515         true
19516 }
19517 run_test 416 "transaction start failure won't cause system hung"
19518
19519 cleanup_417() {
19520         trap 0
19521         do_nodes $(comma_list $(mdts_nodes)) \
19522                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
19523         do_nodes $(comma_list $(mdts_nodes)) \
19524                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
19525         do_nodes $(comma_list $(mdts_nodes)) \
19526                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
19527 }
19528
19529 test_417() {
19530         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19531         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
19532                 skip "Need MDS version at least 2.11.56"
19533
19534         trap cleanup_417 RETURN EXIT
19535
19536         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
19537         do_nodes $(comma_list $(mdts_nodes)) \
19538                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
19539         $LFS migrate -m 0 $DIR/$tdir.1 &&
19540                 error "migrate dir $tdir.1 should fail"
19541
19542         do_nodes $(comma_list $(mdts_nodes)) \
19543                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
19544         $LFS mkdir -i 1 $DIR/$tdir.2 &&
19545                 error "create remote dir $tdir.2 should fail"
19546
19547         do_nodes $(comma_list $(mdts_nodes)) \
19548                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
19549         $LFS mkdir -c 2 $DIR/$tdir.3 &&
19550                 error "create striped dir $tdir.3 should fail"
19551         true
19552 }
19553 run_test 417 "disable remote dir, striped dir and dir migration"
19554
19555 # Checks that the outputs of df [-i] and lfs df [-i] match
19556 #
19557 # usage: check_lfs_df <blocks | inodes> <mountpoint>
19558 check_lfs_df() {
19559         local dir=$2
19560         local inodes
19561         local df_out
19562         local lfs_df_out
19563         local count
19564         local passed=false
19565
19566         # blocks or inodes
19567         [ "$1" == "blocks" ] && inodes= || inodes="-i"
19568
19569         for count in {1..100}; do
19570                 cancel_lru_locks
19571                 sync; sleep 0.2
19572
19573                 # read the lines of interest
19574                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
19575                         error "df $inodes $dir | tail -n +2 failed"
19576                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
19577                         error "lfs df $inodes $dir | grep summary: failed"
19578
19579                 # skip first substrings of each output as they are different
19580                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
19581                 # compare the two outputs
19582                 passed=true
19583                 for i in {1..5}; do
19584                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
19585                 done
19586                 $passed && break
19587         done
19588
19589         if ! $passed; then
19590                 df -P $inodes $dir
19591                 echo
19592                 lfs df $inodes $dir
19593                 error "df and lfs df $1 output mismatch: "      \
19594                       "df ${inodes}: ${df_out[*]}, "            \
19595                       "lfs df ${inodes}: ${lfs_df_out[*]}"
19596         fi
19597 }
19598
19599 test_418() {
19600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19601
19602         local dir=$DIR/$tdir
19603         local numfiles=$((RANDOM % 4096 + 2))
19604         local numblocks=$((RANDOM % 256 + 1))
19605
19606         wait_delete_completed
19607         test_mkdir $dir
19608
19609         # check block output
19610         check_lfs_df blocks $dir
19611         # check inode output
19612         check_lfs_df inodes $dir
19613
19614         # create a single file and retest
19615         echo "Creating a single file and testing"
19616         createmany -o $dir/$tfile- 1 &>/dev/null ||
19617                 error "creating 1 file in $dir failed"
19618         check_lfs_df blocks $dir
19619         check_lfs_df inodes $dir
19620
19621         # create a random number of files
19622         echo "Creating $((numfiles - 1)) files and testing"
19623         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
19624                 error "creating $((numfiles - 1)) files in $dir failed"
19625
19626         # write a random number of blocks to the first test file
19627         echo "Writing $numblocks 4K blocks and testing"
19628         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
19629                 count=$numblocks &>/dev/null ||
19630                 error "dd to $dir/${tfile}-0 failed"
19631
19632         # retest
19633         check_lfs_df blocks $dir
19634         check_lfs_df inodes $dir
19635
19636         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
19637                 error "unlinking $numfiles files in $dir failed"
19638 }
19639 run_test 418 "df and lfs df outputs match"
19640
19641 prep_801() {
19642         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19643         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19644                 skip "Need server version at least 2.9.55"
19645
19646         start_full_debug_logging
19647 }
19648
19649 post_801() {
19650         stop_full_debug_logging
19651 }
19652
19653 barrier_stat() {
19654         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19655                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19656                            awk '/The barrier for/ { print $7 }')
19657                 echo $st
19658         else
19659                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
19660                 echo \'$st\'
19661         fi
19662 }
19663
19664 barrier_expired() {
19665         local expired
19666
19667         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19668                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19669                           awk '/will be expired/ { print $7 }')
19670         else
19671                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
19672         fi
19673
19674         echo $expired
19675 }
19676
19677 test_801a() {
19678         prep_801
19679
19680         echo "Start barrier_freeze at: $(date)"
19681         #define OBD_FAIL_BARRIER_DELAY          0x2202
19682         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19683         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
19684
19685         sleep 2
19686         local b_status=$(barrier_stat)
19687         echo "Got barrier status at: $(date)"
19688         [ "$b_status" = "'freezing_p1'" ] ||
19689                 error "(1) unexpected barrier status $b_status"
19690
19691         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19692         wait
19693         b_status=$(barrier_stat)
19694         [ "$b_status" = "'frozen'" ] ||
19695                 error "(2) unexpected barrier status $b_status"
19696
19697         local expired=$(barrier_expired)
19698         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
19699         sleep $((expired + 3))
19700
19701         b_status=$(barrier_stat)
19702         [ "$b_status" = "'expired'" ] ||
19703                 error "(3) unexpected barrier status $b_status"
19704
19705         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
19706                 error "(4) fail to freeze barrier"
19707
19708         b_status=$(barrier_stat)
19709         [ "$b_status" = "'frozen'" ] ||
19710                 error "(5) unexpected barrier status $b_status"
19711
19712         echo "Start barrier_thaw at: $(date)"
19713         #define OBD_FAIL_BARRIER_DELAY          0x2202
19714         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19715         do_facet mgs $LCTL barrier_thaw $FSNAME &
19716
19717         sleep 2
19718         b_status=$(barrier_stat)
19719         echo "Got barrier status at: $(date)"
19720         [ "$b_status" = "'thawing'" ] ||
19721                 error "(6) unexpected barrier status $b_status"
19722
19723         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19724         wait
19725         b_status=$(barrier_stat)
19726         [ "$b_status" = "'thawed'" ] ||
19727                 error "(7) unexpected barrier status $b_status"
19728
19729         #define OBD_FAIL_BARRIER_FAILURE        0x2203
19730         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
19731         do_facet mgs $LCTL barrier_freeze $FSNAME
19732
19733         b_status=$(barrier_stat)
19734         [ "$b_status" = "'failed'" ] ||
19735                 error "(8) unexpected barrier status $b_status"
19736
19737         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19738         do_facet mgs $LCTL barrier_thaw $FSNAME
19739
19740         post_801
19741 }
19742 run_test 801a "write barrier user interfaces and stat machine"
19743
19744 test_801b() {
19745         prep_801
19746
19747         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19748         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
19749         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
19750         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
19751         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
19752
19753         cancel_lru_locks mdc
19754
19755         # 180 seconds should be long enough
19756         do_facet mgs $LCTL barrier_freeze $FSNAME 180
19757
19758         local b_status=$(barrier_stat)
19759         [ "$b_status" = "'frozen'" ] ||
19760                 error "(6) unexpected barrier status $b_status"
19761
19762         mkdir $DIR/$tdir/d0/d10 &
19763         mkdir_pid=$!
19764
19765         touch $DIR/$tdir/d1/f13 &
19766         touch_pid=$!
19767
19768         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
19769         ln_pid=$!
19770
19771         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
19772         mv_pid=$!
19773
19774         rm -f $DIR/$tdir/d4/f12 &
19775         rm_pid=$!
19776
19777         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
19778
19779         # To guarantee taht the 'stat' is not blocked
19780         b_status=$(barrier_stat)
19781         [ "$b_status" = "'frozen'" ] ||
19782                 error "(8) unexpected barrier status $b_status"
19783
19784         # let above commands to run at background
19785         sleep 5
19786
19787         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
19788         ps -p $touch_pid || error "(10) touch should be blocked"
19789         ps -p $ln_pid || error "(11) link should be blocked"
19790         ps -p $mv_pid || error "(12) rename should be blocked"
19791         ps -p $rm_pid || error "(13) unlink should be blocked"
19792
19793         b_status=$(barrier_stat)
19794         [ "$b_status" = "'frozen'" ] ||
19795                 error "(14) unexpected barrier status $b_status"
19796
19797         do_facet mgs $LCTL barrier_thaw $FSNAME
19798         b_status=$(barrier_stat)
19799         [ "$b_status" = "'thawed'" ] ||
19800                 error "(15) unexpected barrier status $b_status"
19801
19802         wait $mkdir_pid || error "(16) mkdir should succeed"
19803         wait $touch_pid || error "(17) touch should succeed"
19804         wait $ln_pid || error "(18) link should succeed"
19805         wait $mv_pid || error "(19) rename should succeed"
19806         wait $rm_pid || error "(20) unlink should succeed"
19807
19808         post_801
19809 }
19810 run_test 801b "modification will be blocked by write barrier"
19811
19812 test_801c() {
19813         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19814
19815         prep_801
19816
19817         stop mds2 || error "(1) Fail to stop mds2"
19818
19819         do_facet mgs $LCTL barrier_freeze $FSNAME 30
19820
19821         local b_status=$(barrier_stat)
19822         [ "$b_status" = "'expired'" -o "$b_status" = "'failed'" ] || {
19823                 do_facet mgs $LCTL barrier_thaw $FSNAME
19824                 error "(2) unexpected barrier status $b_status"
19825         }
19826
19827         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19828                 error "(3) Fail to rescan barrier bitmap"
19829
19830         do_facet mgs $LCTL barrier_freeze $FSNAME 10
19831
19832         b_status=$(barrier_stat)
19833         [ "$b_status" = "'frozen'" ] ||
19834                 error "(4) unexpected barrier status $b_status"
19835
19836         do_facet mgs $LCTL barrier_thaw $FSNAME
19837         b_status=$(barrier_stat)
19838         [ "$b_status" = "'thawed'" ] ||
19839                 error "(5) unexpected barrier status $b_status"
19840
19841         local devname=$(mdsdevname 2)
19842
19843         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
19844
19845         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19846                 error "(7) Fail to rescan barrier bitmap"
19847
19848         post_801
19849 }
19850 run_test 801c "rescan barrier bitmap"
19851
19852 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
19853 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
19854 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
19855
19856 cleanup_802a() {
19857         trap 0
19858
19859         stopall
19860         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
19861         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
19862         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
19863         setupall
19864 }
19865
19866 test_802a() {
19867
19868         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19869         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19870                 skip "Need server version at least 2.9.55"
19871
19872         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
19873
19874         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19875
19876         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19877                 error "(2) Fail to copy"
19878
19879         trap cleanup_802a EXIT
19880
19881         # sync by force before remount as readonly
19882         sync; sync_all_data; sleep 3; sync_all_data
19883
19884         stopall
19885
19886         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
19887         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
19888         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
19889
19890         echo "Mount the server as read only"
19891         setupall server_only || error "(3) Fail to start servers"
19892
19893         echo "Mount client without ro should fail"
19894         mount_client $MOUNT &&
19895                 error "(4) Mount client without 'ro' should fail"
19896
19897         echo "Mount client with ro should succeed"
19898         mount_client $MOUNT ro ||
19899                 error "(5) Mount client with 'ro' should succeed"
19900
19901         echo "Modify should be refused"
19902         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19903
19904         echo "Read should be allowed"
19905         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19906                 error "(7) Read should succeed under ro mode"
19907
19908         cleanup_802a
19909 }
19910 run_test 802a "simulate readonly device"
19911
19912 test_802b() {
19913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19914         remote_mds_nodsh && skip "remote MDS with nodsh"
19915
19916         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
19917                 skip "readonly option not available"
19918
19919         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
19920
19921         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19922                 error "(2) Fail to copy"
19923
19924         # write back all cached data before setting MDT to readonly
19925         cancel_lru_locks
19926         sync_all_data
19927
19928         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
19929         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
19930
19931         echo "Modify should be refused"
19932         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19933
19934         echo "Read should be allowed"
19935         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19936                 error "(7) Read should succeed under ro mode"
19937
19938         # disable readonly
19939         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
19940 }
19941 run_test 802b "be able to set MDTs to readonly"
19942
19943 test_803() {
19944         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19945         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
19946                 skip "MDS needs to be newer than 2.10.54"
19947
19948         mkdir -p $DIR/$tdir
19949         # Create some objects on all MDTs to trigger related logs objects
19950         for idx in $(seq $MDSCOUNT); do
19951                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
19952                         $DIR/$tdir/dir${idx} ||
19953                         error "Fail to create $DIR/$tdir/dir${idx}"
19954         done
19955
19956         sync; sleep 3
19957         wait_delete_completed # ensure old test cleanups are finished
19958         echo "before create:"
19959         $LFS df -i $MOUNT
19960         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
19961
19962         for i in {1..10}; do
19963                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
19964                         error "Fail to create $DIR/$tdir/foo$i"
19965         done
19966
19967         sync; sleep 3
19968         echo "after create:"
19969         $LFS df -i $MOUNT
19970         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
19971
19972         # allow for an llog to be cleaned up during the test
19973         [ $after_used -ge $((before_used + 10 - 1)) ] ||
19974                 error "before ($before_used) + 10 > after ($after_used)"
19975
19976         for i in {1..10}; do
19977                 rm -rf $DIR/$tdir/foo$i ||
19978                         error "Fail to remove $DIR/$tdir/foo$i"
19979         done
19980
19981         sleep 3 # avoid MDT return cached statfs
19982         wait_delete_completed
19983         echo "after unlink:"
19984         $LFS df -i $MOUNT
19985         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
19986
19987         # allow for an llog to be created during the test
19988         [ $after_used -le $((before_used + 1)) ] ||
19989                 error "after ($after_used) > before ($before_used) + 1"
19990 }
19991 run_test 803 "verify agent object for remote object"
19992
19993 test_804() {
19994         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19995         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
19996                 skip "MDS needs to be newer than 2.10.54"
19997         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19998
19999         mkdir -p $DIR/$tdir
20000         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20001                 error "Fail to create $DIR/$tdir/dir0"
20002
20003         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20004         local dev=$(mdsdevname 2)
20005
20006         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20007                 grep ${fid} || error "NOT found agent entry for dir0"
20008
20009         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20010                 error "Fail to create $DIR/$tdir/dir1"
20011
20012         touch $DIR/$tdir/dir1/foo0 ||
20013                 error "Fail to create $DIR/$tdir/dir1/foo0"
20014         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20015         local rc=0
20016
20017         for idx in $(seq $MDSCOUNT); do
20018                 dev=$(mdsdevname $idx)
20019                 do_facet mds${idx} \
20020                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20021                         grep ${fid} && rc=$idx
20022         done
20023
20024         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20025                 error "Fail to rename foo0 to foo1"
20026         if [ $rc -eq 0 ]; then
20027                 for idx in $(seq $MDSCOUNT); do
20028                         dev=$(mdsdevname $idx)
20029                         do_facet mds${idx} \
20030                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20031                         grep ${fid} && rc=$idx
20032                 done
20033         fi
20034
20035         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20036                 error "Fail to rename foo1 to foo2"
20037         if [ $rc -eq 0 ]; then
20038                 for idx in $(seq $MDSCOUNT); do
20039                         dev=$(mdsdevname $idx)
20040                         do_facet mds${idx} \
20041                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20042                         grep ${fid} && rc=$idx
20043                 done
20044         fi
20045
20046         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20047
20048         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20049                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20050         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20051                 error "Fail to rename foo2 to foo0"
20052         unlink $DIR/$tdir/dir1/foo0 ||
20053                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20054         rm -rf $DIR/$tdir/dir0 ||
20055                 error "Fail to rm $DIR/$tdir/dir0"
20056
20057         for idx in $(seq $MDSCOUNT); do
20058                 dev=$(mdsdevname $idx)
20059                 rc=0
20060
20061                 stop mds${idx}
20062                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20063                         rc=$?
20064                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20065                         error "mount mds$idx failed"
20066                 df $MOUNT > /dev/null 2>&1
20067
20068                 # e2fsck should not return error
20069                 [ $rc -eq 0 ] ||
20070                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20071         done
20072 }
20073 run_test 804 "verify agent entry for remote entry"
20074
20075 cleanup_805() {
20076         do_facet $SINGLEMDS zfs set quota=$old $fsset
20077         unlinkmany $DIR/$tdir/f- 1000000
20078         trap 0
20079 }
20080
20081 test_805() {
20082         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20083         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20084         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20085                 skip "netfree not implemented before 0.7"
20086         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20087                 skip "Need MDS version at least 2.10.57"
20088
20089         local fsset
20090         local freekb
20091         local usedkb
20092         local old
20093         local quota
20094         local pref="osd-zfs.lustre-MDT0000."
20095
20096         # limit available space on MDS dataset to meet nospace issue
20097         # quickly. then ZFS 0.7.2 can use reserved space if asked
20098         # properly (using netfree flag in osd_declare_destroy()
20099         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20100         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20101                 gawk '{print $3}')
20102         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20103         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20104         let "usedkb=usedkb-freekb"
20105         let "freekb=freekb/2"
20106         if let "freekb > 5000"; then
20107                 let "freekb=5000"
20108         fi
20109         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20110         trap cleanup_805 EXIT
20111         mkdir $DIR/$tdir
20112         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20113         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20114         rm -rf $DIR/$tdir || error "not able to remove"
20115         do_facet $SINGLEMDS zfs set quota=$old $fsset
20116         trap 0
20117 }
20118 run_test 805 "ZFS can remove from full fs"
20119
20120 # Size-on-MDS test
20121 check_lsom_data()
20122 {
20123         local file=$1
20124         local size=$($LFS getsom -s $file)
20125         local expect=$(stat -c %s $file)
20126
20127         [[ $size == $expect ]] ||
20128                 error "$file expected size: $expect, got: $size"
20129
20130         local blocks=$($LFS getsom -b $file)
20131         expect=$(stat -c %b $file)
20132         [[ $blocks == $expect ]] ||
20133                 error "$file expected blocks: $expect, got: $blocks"
20134 }
20135
20136 check_lsom_size()
20137 {
20138         local size=$($LFS getsom -s $1)
20139         local expect=$2
20140
20141         [[ $size == $expect ]] ||
20142                 error "$file expected size: $expect, got: $size"
20143 }
20144
20145 test_806() {
20146         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20147                 skip "Need MDS version at least 2.11.52"
20148
20149         local bs=1048576
20150
20151         touch $DIR/$tfile || error "touch $tfile failed"
20152
20153         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20154         save_lustre_params client "llite.*.xattr_cache" > $save
20155         lctl set_param llite.*.xattr_cache=0
20156         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20157
20158         # single-threaded write
20159         echo "Test SOM for single-threaded write"
20160         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20161                 error "write $tfile failed"
20162         check_lsom_size $DIR/$tfile $bs
20163
20164         local num=32
20165         local size=$(($num * $bs))
20166         local offset=0
20167         local i
20168
20169         echo "Test SOM for single client multi-threaded($num) write"
20170         $TRUNCATE $DIR/$tfile 0
20171         for ((i = 0; i < $num; i++)); do
20172                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20173                 local pids[$i]=$!
20174                 offset=$((offset + $bs))
20175         done
20176         for (( i=0; i < $num; i++ )); do
20177                 wait ${pids[$i]}
20178         done
20179         check_lsom_size $DIR/$tfile $size
20180
20181         $TRUNCATE $DIR/$tfile 0
20182         for ((i = 0; i < $num; i++)); do
20183                 offset=$((offset - $bs))
20184                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20185                 local pids[$i]=$!
20186         done
20187         for (( i=0; i < $num; i++ )); do
20188                 wait ${pids[$i]}
20189         done
20190         check_lsom_size $DIR/$tfile $size
20191
20192         # multi-client wirtes
20193         num=$(get_node_count ${CLIENTS//,/ })
20194         size=$(($num * $bs))
20195         offset=0
20196         i=0
20197
20198         echo "Test SOM for multi-client ($num) writes"
20199         $TRUNCATE $DIR/$tfile 0
20200         for client in ${CLIENTS//,/ }; do
20201                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20202                 local pids[$i]=$!
20203                 i=$((i + 1))
20204                 offset=$((offset + $bs))
20205         done
20206         for (( i=0; i < $num; i++ )); do
20207                 wait ${pids[$i]}
20208         done
20209         check_lsom_size $DIR/$tfile $offset
20210
20211         i=0
20212         $TRUNCATE $DIR/$tfile 0
20213         for client in ${CLIENTS//,/ }; do
20214                 offset=$((offset - $bs))
20215                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20216                 local pids[$i]=$!
20217                 i=$((i + 1))
20218         done
20219         for (( i=0; i < $num; i++ )); do
20220                 wait ${pids[$i]}
20221         done
20222         check_lsom_size $DIR/$tfile $size
20223
20224         # verify truncate
20225         echo "Test SOM for truncate"
20226         $TRUNCATE $DIR/$tfile 1048576
20227         check_lsom_size $DIR/$tfile 1048576
20228         $TRUNCATE $DIR/$tfile 1234
20229         check_lsom_size $DIR/$tfile 1234
20230
20231         # verify SOM blocks count
20232         echo "Verify SOM block count"
20233         $TRUNCATE $DIR/$tfile 0
20234         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20235                 error "failed to write file $tfile"
20236         check_lsom_data $DIR/$tfile
20237 }
20238 run_test 806 "Verify Lazy Size on MDS"
20239
20240 test_807() {
20241         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20242         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20243                 skip "Need MDS version at least 2.11.52"
20244
20245         # Registration step
20246         changelog_register || error "changelog_register failed"
20247         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20248         changelog_users $SINGLEMDS | grep -q $cl_user ||
20249                 error "User $cl_user not found in changelog_users"
20250
20251         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20252         save_lustre_params client "llite.*.xattr_cache" > $save
20253         lctl set_param llite.*.xattr_cache=0
20254         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20255
20256         rm -rf $DIR/$tdir || error "rm $tdir failed"
20257         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20258         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20259         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20260         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20261                 error "truncate $tdir/trunc failed"
20262
20263         local bs=1048576
20264         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20265                 error "write $tfile failed"
20266
20267         # multi-client wirtes
20268         local num=$(get_node_count ${CLIENTS//,/ })
20269         local offset=0
20270         local i=0
20271
20272         echo "Test SOM for multi-client ($num) writes"
20273         touch $DIR/$tfile || error "touch $tfile failed"
20274         $TRUNCATE $DIR/$tfile 0
20275         for client in ${CLIENTS//,/ }; do
20276                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20277                 local pids[$i]=$!
20278                 i=$((i + 1))
20279                 offset=$((offset + $bs))
20280         done
20281         for (( i=0; i < $num; i++ )); do
20282                 wait ${pids[$i]}
20283         done
20284
20285         sleep 5
20286         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20287         check_lsom_data $DIR/$tdir/trunc
20288         check_lsom_data $DIR/$tdir/single_dd
20289         check_lsom_data $DIR/$tfile
20290
20291         rm -rf $DIR/$tdir
20292         # Deregistration step
20293         changelog_deregister || error "changelog_deregister failed"
20294 }
20295 run_test 807 "verify LSOM syncing tool"
20296
20297 check_som_nologged()
20298 {
20299         local lines=$($LFS changelog $FSNAME-MDT0000 |
20300                 grep 'x=trusted.som' | wc -l)
20301         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
20302 }
20303
20304 test_808() {
20305         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
20306                 skip "Need MDS version at least 2.11.55"
20307
20308         # Registration step
20309         changelog_register || error "changelog_register failed"
20310
20311         touch $DIR/$tfile || error "touch $tfile failed"
20312         check_som_nologged
20313
20314         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
20315                 error "write $tfile failed"
20316         check_som_nologged
20317
20318         $TRUNCATE $DIR/$tfile 1234
20319         check_som_nologged
20320
20321         $TRUNCATE $DIR/$tfile 1048576
20322         check_som_nologged
20323
20324         # Deregistration step
20325         changelog_deregister || error "changelog_deregister failed"
20326 }
20327 run_test 808 "Check trusted.som xattr not logged in Changelogs"
20328
20329 check_som_nodata()
20330 {
20331         $LFS getsom $1
20332         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
20333 }
20334
20335 test_809() {
20336         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20337                 skip "Need MDS version at least 2.11.56"
20338
20339         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
20340                 error "failed to create DoM-only file $DIR/$tfile"
20341         touch $DIR/$tfile || error "touch $tfile failed"
20342         check_som_nodata $DIR/$tfile
20343
20344         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
20345                 error "write $tfile failed"
20346         check_som_nodata $DIR/$tfile
20347
20348         $TRUNCATE $DIR/$tfile 1234
20349         check_som_nodata $DIR/$tfile
20350
20351         $TRUNCATE $DIR/$tfile 4097
20352         check_som_nodata $DIR/$file
20353 }
20354 run_test 809 "Verify no SOM xattr store for DoM-only files"
20355
20356 test_810() {
20357         local ORIG
20358         local CSUM
20359
20360         # t10 seem to dislike partial pages
20361         lctl set_param osc.*.checksum_type=adler
20362         lctl set_param fail_loc=0x411
20363         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
20364         ORIG=$(md5sum $DIR/$tfile)
20365         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
20366         CSUM=$(md5sum $DIR/$tfile)
20367         set_checksum_type adler
20368         if [ "$ORIG" != "$CSUM" ]; then
20369                 error "$ORIG != $CSUM"
20370         fi
20371 }
20372 run_test 810 "partial page writes on ZFS (LU-11663)"
20373
20374 test_811() {
20375         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
20376                 skip "Need MDS version at least 2.11.56"
20377
20378         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
20379         do_facet mds1 $LCTL set_param fail_loc=0x165
20380         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
20381
20382         stop mds1
20383         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20384
20385         sleep 5
20386         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
20387                 error "MDD orphan cleanup thread not quit"
20388 }
20389 run_test 811 "orphan name stub can be cleaned up in startup"
20390
20391 test_812() {
20392         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
20393                 skip "OST < 2.12.51 doesn't support this fail_loc"
20394
20395         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20396         # ensure ost1 is connected
20397         stat $DIR/$tfile >/dev/null || error "can't stat"
20398         wait_osc_import_state client ost1 FULL
20399         # no locks, no reqs to let the connection idle
20400         cancel_lru_locks osc
20401
20402         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
20403 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
20404         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
20405         wait_osc_import_state client ost1 CONNECTING
20406         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
20407
20408         stat $DIR/$tfile >/dev/null || error "can't stat file"
20409 }
20410 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
20411
20412 test_813() {
20413         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
20414         [ -z "$file_heat_sav" ] && skip "no file heat support"
20415
20416         local readsample
20417         local writesample
20418         local readbyte
20419         local writebyte
20420         local readsample1
20421         local writesample1
20422         local readbyte1
20423         local writebyte1
20424
20425         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
20426         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
20427
20428         $LCTL set_param -n llite.*.file_heat=1
20429         echo "Turn on file heat"
20430         echo "Period second: $period_second, Decay percentage: $decay_pct"
20431
20432         echo "QQQQ" > $DIR/$tfile
20433         echo "QQQQ" > $DIR/$tfile
20434         echo "QQQQ" > $DIR/$tfile
20435         cat $DIR/$tfile > /dev/null
20436         cat $DIR/$tfile > /dev/null
20437         cat $DIR/$tfile > /dev/null
20438         cat $DIR/$tfile > /dev/null
20439
20440         local out=$($LFS heat_get $DIR/$tfile)
20441
20442         $LFS heat_get $DIR/$tfile
20443         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20444         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20445         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20446         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20447
20448         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
20449         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
20450         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
20451         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
20452
20453         sleep $((period_second + 3))
20454         echo "Sleep $((period_second + 3)) seconds..."
20455         # The recursion formula to calculate the heat of the file f is as
20456         # follow:
20457         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
20458         # Where Hi is the heat value in the period between time points i*I and
20459         # (i+1)*I; Ci is the access count in the period; the symbol P refers
20460         # to the weight of Ci.
20461         out=$($LFS heat_get $DIR/$tfile)
20462         $LFS heat_get $DIR/$tfile
20463         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20464         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20465         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20466         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20467
20468         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
20469                 error "read sample ($readsample) is wrong"
20470         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
20471                 error "write sample ($writesample) is wrong"
20472         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
20473                 error "read bytes ($readbyte) is wrong"
20474         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
20475                 error "write bytes ($writebyte) is wrong"
20476
20477         echo "QQQQ" > $DIR/$tfile
20478         echo "QQQQ" > $DIR/$tfile
20479         echo "QQQQ" > $DIR/$tfile
20480         cat $DIR/$tfile > /dev/null
20481         cat $DIR/$tfile > /dev/null
20482         cat $DIR/$tfile > /dev/null
20483         cat $DIR/$tfile > /dev/null
20484
20485         sleep $((period_second + 3))
20486         echo "Sleep $((period_second + 3)) seconds..."
20487
20488         out=$($LFS heat_get $DIR/$tfile)
20489         $LFS heat_get $DIR/$tfile
20490         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20491         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20492         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20493         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20494
20495         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
20496                 4 * $decay_pct) / 100") -eq 1 ] ||
20497                 error "read sample ($readsample1) is wrong"
20498         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
20499                 3 * $decay_pct) / 100") -eq 1 ] ||
20500                 error "write sample ($writesample1) is wrong"
20501         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
20502                 20 * $decay_pct) / 100") -eq 1 ] ||
20503                 error "read bytes ($readbyte1) is wrong"
20504         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
20505                 15 * $decay_pct) / 100") -eq 1 ] ||
20506                 error "write bytes ($writebyte1) is wrong"
20507
20508         echo "Turn off file heat for the file $DIR/$tfile"
20509         $LFS heat_set -o $DIR/$tfile
20510
20511         echo "QQQQ" > $DIR/$tfile
20512         echo "QQQQ" > $DIR/$tfile
20513         echo "QQQQ" > $DIR/$tfile
20514         cat $DIR/$tfile > /dev/null
20515         cat $DIR/$tfile > /dev/null
20516         cat $DIR/$tfile > /dev/null
20517         cat $DIR/$tfile > /dev/null
20518
20519         out=$($LFS heat_get $DIR/$tfile)
20520         $LFS heat_get $DIR/$tfile
20521         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20522         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20523         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20524         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20525
20526         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20527         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20528         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20529         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20530
20531         echo "Trun on file heat for the file $DIR/$tfile"
20532         $LFS heat_set -O $DIR/$tfile
20533
20534         echo "QQQQ" > $DIR/$tfile
20535         echo "QQQQ" > $DIR/$tfile
20536         echo "QQQQ" > $DIR/$tfile
20537         cat $DIR/$tfile > /dev/null
20538         cat $DIR/$tfile > /dev/null
20539         cat $DIR/$tfile > /dev/null
20540         cat $DIR/$tfile > /dev/null
20541
20542         out=$($LFS heat_get $DIR/$tfile)
20543         $LFS heat_get $DIR/$tfile
20544         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20545         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20546         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20547         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20548
20549         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
20550         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
20551         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
20552         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
20553
20554         $LFS heat_set -c $DIR/$tfile
20555         $LCTL set_param -n llite.*.file_heat=0
20556         echo "Turn off file heat support for the Lustre filesystem"
20557
20558         echo "QQQQ" > $DIR/$tfile
20559         echo "QQQQ" > $DIR/$tfile
20560         echo "QQQQ" > $DIR/$tfile
20561         cat $DIR/$tfile > /dev/null
20562         cat $DIR/$tfile > /dev/null
20563         cat $DIR/$tfile > /dev/null
20564         cat $DIR/$tfile > /dev/null
20565
20566         out=$($LFS heat_get $DIR/$tfile)
20567         $LFS heat_get $DIR/$tfile
20568         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20569         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20570         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20571         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20572
20573         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20574         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20575         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20576         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20577
20578         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
20579         rm -f $DIR/$tfile
20580 }
20581 run_test 813 "File heat verfication"
20582
20583 #
20584 # tests that do cleanup/setup should be run at the end
20585 #
20586
20587 test_900() {
20588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20589         local ls
20590
20591         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
20592         $LCTL set_param fail_loc=0x903
20593
20594         cancel_lru_locks MGC
20595
20596         FAIL_ON_ERROR=true cleanup
20597         FAIL_ON_ERROR=true setup
20598 }
20599 run_test 900 "umount should not race with any mgc requeue thread"
20600
20601 complete $SECONDS
20602 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
20603 check_and_cleanup_lustre
20604 if [ "$I_MOUNTED" != "yes" ]; then
20605         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
20606 fi
20607 exit_status